-
Notifications
You must be signed in to change notification settings - Fork 118
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
Enable custom network signing #1444
Conversation
@@ -159,18 +160,6 @@ function accountUpdatesToCallForest<A extends { body: { callDepth: number } }>( | |||
return forest; | |||
} | |||
|
|||
const zkAppBodyPrefix = (network: string) => { |
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.
moved this into mina-signer/src/signature.js
for shared use with o1js
expect(hashTestnet).toEqual(hashSnarkyTestnet.toBigInt()); | ||
expect(hashMainnet).toEqual(hashSnarkyMainnet.toBigInt()); | ||
}); | ||
test( |
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.
cleaned this up a little by utilizing RandomTransaction.networkId
let commitment = callForestHash(callForest, 'testnet'); | ||
expect(commitment).toEqual(FieldConst.toBigint(ocamlCommitments.commitment)); | ||
}); | ||
test( |
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 now tests all network id types
} | ||
} | ||
|
||
const createCustomPrefix = (prefix: string) => { |
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.
OCaml uses a *
padding to 20
bytes
@@ -23,26 +23,29 @@ function checkConsistentSingle( | |||
msg: Field, | |||
key: PrivateKey, | |||
keySnarky: PrivateKeySnarky, | |||
pk: PublicKey | |||
pk: PublicKey, | |||
networkId: string |
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.
some cleanup, tests all three network cases now
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.
Signature in o1js (not mina-signer) has still hard-coded testnet prefix.
good catch! |
The network id was purposefully left out as a parameter in the userland signature methods: the in-SNARK We only happen to reuse the same signing functions also used by transaction signatures, so we had to pick some choice of Unless there is a specific reason to make these signatures network-specific in the PR, I'd be in favor of reverting these changes. Adding the networkId parameter just adds confusion IMO. |
Hmm given that you can specify a custom message anyway (with a custom nonce), this really can be reverted. But curious to know if @MartinOndejka sees an explicit need for this? |
Not at all, I just remember that it was a little confusing a while back when I found out that it has hardcoded |
@Trivo25 maybe it would be good to add a comment to these methods explaining why they hard-code testnet |
src/mina-signer/src/types.ts
Outdated
@@ -9,7 +9,7 @@ export type Field = number | bigint | string; | |||
export type PublicKey = string; | |||
export type PrivateKey = string; | |||
export type Signature = SignatureJson; | |||
export type NetworkId = 'mainnet' | 'testnet'; | |||
export type NetworkId = string; |
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.
Maybe something like export type NetworkId = 'mainnet' | 'testnet' | string;
for better intellisense?
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.
I think TS would just collapse that to string
, because 'mainnet'
and 'testnet'
are contained in string
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.
so after all, we can probably just remove the NetworkId
export which caused us to release 2 or 3 new versions in a row 😆
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.
btw, now we also need those runtime checks which I made you remove @shimkiv 😅
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.
damn, I wonder if we should keep the detailed type somehow. Maybe something like
type NetworkId = 'mainnet' | 'testnet' | { custom: string }
@Trivo25 wdyt
expect(hashTestnet).toEqual(hashSnarkyTestnet.toBigInt()); | ||
expect(hashMainnet).toEqual(hashSnarkyMainnet.toBigInt()); | ||
}); | ||
test( |
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.
@Trivo25
Throughout different tests we check that signatures match like testnet <-> testnet
but should we also check that the resulting signatures are indeed different for different networks? Like testnet <-> mainnet
should always differ.
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.
Yes, we should! And we do
For example, further down we verify against a different network and expect the verification to fail
expect(
verify(sigFieldElements, networkId === 'mainnet' ? 'testnet' : 'mainnet')
).toEqual(false);
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.
but I added a check that the hash doesnt match another networks hash!
if (!options?.network) { | ||
throw Error('Invalid Specified Network'); | ||
} | ||
const specifiedNetwork = options.network.toLowerCase(); |
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 no longer needed since the type now is 'testnet' | 'mainnet'
which already is lower case
expect(hashTestnet).toEqual(hashSnarkyTestnet.toBigInt()); | ||
expect(hashMainnet).toEqual(hashSnarkyMainnet.toBigInt()); | ||
}); | ||
test( |
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.
but I added a check that the hash doesnt match another networks hash!
expect(okMainnetTestnet).toEqual(false); | ||
expect(okTestnetMainnet).toEqual(false); | ||
expect(okMainnetMainnet).toEqual(true); | ||
expect(verifyFieldElement(sig, msg, pk, networkId)).toEqual(true); |
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.
test is now condensed by using networkId
as input
export type NetworkId = 'mainnet' | 'testnet'; | ||
export type NetworkId = 'mainnet' | 'testnet' | { custom: string }; | ||
|
||
export const NetworkId = { |
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.
internal helper to get the plain networkId
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.
nicely done!
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.
awesome!
This PR enables custom network signing and verification, all across our stack (o1js and mina-signer). This feature unlocks the use of o1js and mina-signer with layer 2s/3s or chains isomorphic to Mina. All while maintaining backwards compatibility
bindings o1-labs/o1js-bindings#247
closes #1149