-
Notifications
You must be signed in to change notification settings - Fork 71
feat: PQ signature support + V42 updates #944
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
base: main
Are you sure you want to change the base?
Changes from all commits
ede747b
6e480ba
2715457
712c16c
c5220f1
19ea358
16a36ba
9ebd6a2
fd7254c
8d2e08d
ed9d151
f9943f3
1baabcf
0449e83
6f289fa
4ca5392
cb1182a
fde27af
e7954cd
0c80975
df65ab2
7709155
ecb76d3
41e94df
ebd79d0
48da3ee
3ac006a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| package com.algorand.algosdk.account; | ||
|
|
||
| import com.algorand.algosdk.crypto.*; | ||
| import com.algorand.algosdk.signer.Falcon1024AlgorandSigner; | ||
| import com.algorand.algosdk.signer.PQAlgorandSigner; | ||
| import com.algorand.algosdk.transaction.SignedTransaction; | ||
| import com.algorand.algosdk.transaction.Transaction; | ||
| import com.algorand.algosdk.transaction.TxnSigner; | ||
|
|
@@ -82,6 +84,39 @@ public void appendMultiSig(PrivateKey privateKey) | |
| signerAccount.appendToLogicsig(this.lsig); | ||
| } | ||
|
|
||
| /** | ||
| * Creates a new delegated LogicSigAccount whose delegating account is a | ||
| * post-quantum account, signing the program in one call with the supplied | ||
| * callback-based signer. | ||
| * <p> | ||
| * This is the callback-based counterpart of the | ||
| * {@code (logic, args, privateKey)} constructor. Post-quantum delegation | ||
| * does not support multisig; there is no multisig variant of this factory. | ||
| * @param logic the bytes of the program | ||
| * @param args the arguments of the program (may be null) | ||
| * @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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PQ got one-call factories ( |
||
| throws Exception { | ||
| Objects.requireNonNull(signer, "signer must not be null"); | ||
| LogicsigSignature lsig = new LogicsigSignature(logic, args); | ||
| signer.signLogicsig(lsig); | ||
| return new LogicSigAccount(lsig, null); | ||
| } | ||
|
|
||
| /** | ||
| * {@link #delegatedPQ} fixed to a Falcon-1024 signer. | ||
| * @param logic the bytes of the program | ||
| * @param args the arguments of the program (may be null) | ||
| * @param signer the Falcon-1024 signer of the delegating account | ||
| * @return a delegated LogicSigAccount carrying the post-quantum signature | ||
| */ | ||
| public static LogicSigAccount delegatedFalcon1024(byte[] logic, List<byte[]> args, Falcon1024AlgorandSigner signer) | ||
| throws Exception { | ||
| return delegatedPQ(logic, args, signer); | ||
| } | ||
|
|
||
| /** | ||
| * Creates a new delegated LogicSigAccount from existing LogicSig | ||
| * @param lsig is an existing LogicSig. | ||
|
|
@@ -99,7 +134,7 @@ public LogicSigAccount(LogicsigSignature lsig, Ed25519PublicKey signerPublicKey) | |
| boolean hasMsig = lsig.msig != null; | ||
|
|
||
| if (lsig.sigCount() > 1) | ||
| throw new IllegalArgumentException("Logicsig has too many signatures, at most one of Sig, Msig, or LMsig may be defined"); | ||
| throw new IllegalArgumentException("Logicsig has too many signatures, at most one of Sig, Msig, LMsig, or PQsig may be defined"); | ||
| if (hasSig) { | ||
| if (signerPublicKey == null) | ||
| throw new IllegalArgumentException("Cannot generate LogicSigAccount from single-signed LogicSig and a null public key"); | ||
|
|
@@ -110,7 +145,7 @@ public LogicSigAccount(LogicsigSignature lsig, Ed25519PublicKey signerPublicKey) | |
| return; | ||
| } | ||
| if (signerPublicKey != null) | ||
| throw new IllegalArgumentException("Cannot generate LogicSigAccount from multi-sig LogicSig and a public key"); | ||
| throw new IllegalArgumentException("Cannot generate LogicSigAccount from multi-sig or post-quantum LogicSig and a public key"); | ||
| this.lsig = lsig; | ||
| this.sigKey = null; | ||
| } | ||
|
|
@@ -123,7 +158,8 @@ public boolean isDelegated() { | |
| boolean hasSig = this.lsig.sig != null; | ||
| boolean hasLmsig = this.lsig.lmsig != null; | ||
| boolean hasMsig = this.lsig.msig != null; | ||
| return hasSig || hasLmsig || hasMsig; | ||
| boolean hasPQsig = this.lsig.pqsig != null; | ||
| return hasSig || hasLmsig || hasMsig || hasPQsig; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -136,13 +172,19 @@ public Address getAddress() throws NoSuchAlgorithmException, IllegalArgumentExce | |
| boolean hasSig = this.lsig.sig != null; | ||
| boolean hasLmsig = this.lsig.lmsig != null; | ||
| boolean hasMsig = this.lsig.msig != null; | ||
| boolean hasPQsig = this.lsig.pqsig != null; | ||
|
|
||
| if (this.lsig.sigCount() > 1) | ||
| throw new IllegalArgumentException("Logicsig has too many signatures, at most one of Sig, Msig, or LMsig may be defined"); | ||
| throw new IllegalArgumentException("Logicsig has too many signatures, at most one of Sig, Msig, LMsig, or PQsig may be defined"); | ||
| if (hasSig) { | ||
| byte[] sigKeyRaw = this.sigKey.getBytes(); | ||
| return new Address(sigKeyRaw); | ||
| } | ||
| if (hasPQsig) { | ||
| // The signature carries the scheme, salt and public key of the | ||
| // delegating account, so it fully determines the address. | ||
| return PQAddress.fromSignature(this.lsig.pqsig); | ||
| } | ||
| if (hasLmsig) { | ||
| List<Ed25519PublicKey> pkFromSubSig = new ArrayList<>(); | ||
| for (MultisigSignature.MultisigSubsig subSig : this.lsig.lmsig.subsigs) | ||
|
|
||
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-lib/README.mdalready covers removing this oncefalcon-det1024hits 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.