[WIP] feat: pq sig - #944
Conversation
…ote fields, app args, extra app pages, lsig size)
…BoxRef types used boxed Long/byte[] fields, so NON_DEFAULT serialization never suppressed zero indices or empty box names, breaking access list usage of index 0 shorthands
…not set, causing msgpack key set to nil instead of being actually absent
mrcointreau
left a comment
There was a problem hiding this comment.
Addresses, signing preimages, wire format and test vectors match js and py implementations with no breaking changes. The real differences between the Java implementation and the js/py ones are at design-level:
- Non-canonical salt management: Java resolves a pqsig's address from the salt it carries, as-is while js/py reject non-canonical salts.
- Verification methods: in js/py
verify()was deprecated and returns false for pqsigs, since we can't check validity without the falcon package; Java returns true on the address-envelope match (partly becauseAccount.signLogicTransactionWithAddressgates signing on verify()). If we decide to align Java, the fix is contained and non-breaking: return false + move the envelope check into the signing path. - Vendored falcon-det1024: currently used by the cucumber steps and the falcon vector unit tests, goes away once the library is on Maven Central. One thing to fix before the next release regardless: the top-level
<repositories>block ships verbatim in the published pom (which is immutable), so swap it for an install-file step or scope it in a profile.
We could ship this as-is and refine it later on, I'd ask @joe-p to be sure about the plan.
| */ | ||
| public static Address fromSignature(PQSignature pqsig) throws NoSuchAlgorithmException { | ||
| Objects.requireNonNull(pqsig, "pqsig must not be null"); | ||
| return derive(pqsig.scheme, pqsig.salt, pqsig.publicKey); |
There was a problem hiding this comment.
Just flagging a divergence: js/py reject a pqsig whose salt is not the canonical one, while here the address is resolved from the carried salt as-is (matching go consensus), with explicit-salt APIs on top. So the same blob raises in js/py and works in Java. This may well be fine, just worth knowing the implementations differ.
There was a problem hiding this comment.
This divergence came from a talk with @iglosiggio and how he was approaching this in golang. He made a good point that if for whatever reason somebody has a non-canonical salt sig, and this is valid for consensus, then we should really support it even if on generation we prioritize the canonical salt.
I do believe it's worth keeping parity as strictly as possible between SDKs, so we should decide what we want to do in general when we do a 4-sdk-wide parity review.
| // delegating account. go-algorand-sdk's VerifyLogicSig skips post- | ||
| // quantum signatures entirely and returns true. | ||
| try { | ||
| return PQAddress.fromSignature(this.pqsig).equals(singleSigner); |
There was a problem hiding this comment.
Another divergence to be aware of: js/py sdks deprecated verify() and return false for a pqsig (the SDK can't validate falcon locally), while here it returns true when the address derived from the envelope matches, without reading the signature bytes. Java kept true because signLogicTransactionWithAddress gates signing on verify. Could be fine either way, just worth knowing the implementations differ.
| <repositories> | ||
| <repository> | ||
| <id>vendored-test-lib</id> | ||
| <url>file://${project.basedir}/test-lib</url> | ||
| <releases><enabled>true</enabled></releases> | ||
| <snapshots><enabled>false</enabled></snapshots> | ||
| </repository> | ||
| </repositories> |
There was a problem hiding this comment.
test-lib/README.md already covers removing this once falcon-det1024 hits Maven Central, but there's no guard for the opposite ordering: if an SDK release goes out first, this block ships in the (immutable) published pom, since both deploy paths publish the raw pom and there's no flatten plugin. If a release could plausibly land before the falcon publish, cheap insurance is moving the block inside a profile or resolving the jar via an install-file step; otherwise fine as-is.
| * @param signer the post-quantum signer of the delegating account | ||
| * @return a delegated LogicSigAccount carrying the post-quantum signature | ||
| */ | ||
| public static LogicSigAccount delegatedPQ(byte[] logic, List<byte[]> args, PQAlgorandSigner signer) |
There was a problem hiding this comment.
PQ got one-call factories (delegatedPQ/delegatedFalcon1024) but there's no ed25519-callback equivalent, while js/py cover both with signWithSigner/sign_with_signer. The two-step composition works (signLogicsig + the verifying ctor), so just a nit: consider a matching delegated(logic, args, Ed25519AlgorandSigner) factory
…r.java Co-authored-by: mrcointreau <45950216+mrcointreau@users.noreply.github.com>
…andSigner.java Co-authored-by: mrcointreau <45950216+mrcointreau@users.noreply.github.com>
49d39e8 to
e606752
Compare
Co-authored-by: mrcointreau <45950216+mrcointreau@users.noreply.github.com>
4c3858f to
6d970fc
Compare
[WIP]
Note that the falcon-det1024 package is vendored in, using this. When that one is properly published, we can use it as a regular dep. instead, same as the rest of SDKs.