-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runtime-sdk: Add sr25519 support in EVM precompiles #2073
Conversation
✅ Deploy Preview for oasisprotocol-oasis-sdk canceled.
|
087bccb
to
f8d82ba
Compare
@@ -60,6 +61,27 @@ impl PublicKey { | |||
.map_err(|_| Error::VerificationFailed) | |||
} | |||
|
|||
/// Verify a signature. | |||
pub fn verify_raw( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not in line with other signers, where you have /// Verify signature without using any domain separation scheme.
, so optionally we could think about renaming this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This matches the polkadot implementation.
f8d82ba
to
1a596b9
Compare
Constructing STROBE/Merlin transcript requires access to the underlying KeccakF[1600] permutation function, I'm wary that implementing sr25519 signing alone may not be enough if people end up reverting to Solidity to construct the message to be signed, or if the sr25519 signer makes assumption about the transcript which makes it impossible to use for other things. |
We can always introduce additional signature modes with different transcripts if needed. This is the easiest way to add into the existing framework, it would be good to know if it is sufficient for the use cases at hand. |
Good news: current implementation can verify test case signature. Bad news:
// Key derivation from polkadot test cases
// See: https://github.com/polkadot-js/wasm/blob/10010830094e7d033bd11b16c5e3bc01a7045309/packages/wasm-crypto/src/rs/sr25519.rs#L176
const secretSeed = getBytes("0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e");
const secretKey = sr25519.secretFromSeed(secretSeed);
const publicKey = sr25519.getPublicKey(secretKey);
expect(hexlify(publicKey)).eq("0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a");
// Known valid signature
const msg = new TextEncoder().encode("<Bytes>message to sign</Bytes>");
const sig = getBytes("0x48ce2c90e08651adfc8ecef84e916f6d1bb51ebebd16150ee12df247841a5437951ea0f9d632ca165e6ab391532e75e701be6a1caa88c8a6bcca3511f55b4183");
const sigSigner = getBytes("0xf84d048da2ddae2d9d8fd6763f469566e8817a26114f39408de15547f6d47805");
// Verify JS implementation matches polkadot test case signature
const isValid = sr25519.verify(msg, sig, sigSigner);
expect(isValid).eq(true);
const CONTEXT = new TextEncoder().encode('substrate');
// Verify on-chain implementation also works
const result = await se.testVerify(6, sigSigner, CONTEXT, msg, sig);
expect(result).eq(true);
// Test key generation
const generatedKey = await se.testKeygen(6, secretSeed);
// 64 byte secret, appended with 32 byte public key
expect(getBytes(generatedKey.secretKey).length).eq(96);
expect(hexlify(getBytes(generatedKey.secretKey).slice(64))).eq(generatedKey.publicKey);
// JS can verify on-chain signed message
const onchainSigned = await se.testSign(6, generatedKey.secretKey, CONTEXT, msg);
const jsVerify = sr25519.verify(msg, getBytes(onchainSigned), getBytes(generatedKey.publicKey));
expect(jsVerify).eq(true);
// And on-chain can verify on-chain signed message
expect(await se.testVerify(6, generatedKey.publicKey, CONTEXT, msg, onchainSigned)).eq(true);
// JS roundtrip with on-chain generated keypair
const jsSigned = sr25519.sign(getBytes(generatedKey.secretKey).slice(0, 64), msg);
expect(sr25519.verify(msg, jsSigned, getBytes(generatedKey.publicKey))).eq(false); // FAIL
// on-chain verify JS signed message
const onchainVerify = await se.testVerify(6, generatedKey.publicKey, CONTEXT, msg, jsSigned);
expect(onchainVerify).eq(false); // FAIL |
1a596b9
to
2af15ac
Compare
The other thing seems to be that there are two ways to encode a keypair:
It looks like we are using |
4b8a0fe
to
7af2344
Compare
7af2344
to
7621921
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This matches the Polkadot implementation and passes the tests I made in sapphire-contracts: oasisprotocol/sapphire-paratime#469
…ostko/feature/sr25519-sign f3c7873
…/kostko/feature/sr25519-sign f3c7873
…sisprotocol/kostko/feature/sr25519-sign f3c7873
…oasisprotocol/kostko/feature/sr25519-sign f3c7873
Fixes #1968