From 3f9edde19f2492f6fff60f4c18c7a7f6f4d05f2f Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 11 Oct 2018 18:37:24 +0100 Subject: [PATCH 1/4] Generate a valid Jubjub point for SpendDescription test vectors --- sapling_jubjub.py | 8 ++++++++ transaction.py | 6 +++--- zip_0243.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/sapling_jubjub.py b/sapling_jubjub.py index 6bfc31a..b8d012b 100644 --- a/sapling_jubjub.py +++ b/sapling_jubjub.py @@ -142,6 +142,14 @@ JUBJUB_D = Fq(-10240) / Fq(10241) JUBJUB_COFACTOR = Fr(8) class Point(object): + @staticmethod + def rand(rand): + while True: + data = rand.b(32) + p = Point.from_bytes(data) + if p: + return p + @staticmethod def from_bytes(buf): assert len(buf) == 32 diff --git a/transaction.py b/transaction.py index c81acef..39ab9b4 100644 --- a/transaction.py +++ b/transaction.py @@ -2,7 +2,7 @@ import struct from sapling_generators import find_group_hash, SPENDING_KEY_BASE -from sapling_jubjub import Fq +from sapling_jubjub import Fq, Point from sapling_utils import leos2ip from zc_utils import write_compact_size @@ -80,7 +80,7 @@ class SpendDescription(object): self.cv = find_group_hash(b'TVRandPt', rand.b(32)) self.anchor = Fq(leos2ip(rand.b(32))) self.nullifier = rand.b(32) - self.rk = rand.b(32) + self.rk = Point.rand(rand) self.proof = GrothProof(rand) self.spendAuthSig = rand.b(64) # Invalid @@ -89,7 +89,7 @@ class SpendDescription(object): bytes(self.cv) + bytes(self.anchor) + self.nullifier + - self.rk + + bytes(self.rk) + bytes(self.proof) + self.spendAuthSig ) diff --git a/zip_0243.py b/zip_0243.py index 9ec1a31..bd558b6 100644 --- a/zip_0243.py +++ b/zip_0243.py @@ -31,7 +31,7 @@ def getHashShieldedSpends(tx): digest.update(bytes(desc.cv)) digest.update(bytes(desc.anchor)) digest.update(desc.nullifier) - digest.update(desc.rk) + digest.update(bytes(desc.rk)) digest.update(bytes(desc.proof)) return digest.digest() From 73b8401b9ababbd3db450e61074a618c1024176f Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 11 Oct 2018 18:38:33 +0100 Subject: [PATCH 2/4] Use i64 for amounts in Rust test vectors --- zip_0143.py | 2 +- zip_0243.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/zip_0143.py b/zip_0143.py index 5d0ffb5..273059e 100644 --- a/zip_0143.py +++ b/zip_0143.py @@ -156,7 +156,7 @@ def main(): 'rust_fmt': lambda x: None if x == -1 else Some(x), }), ('hash_type', 'u32'), - ('amount', 'u64'), + ('amount', 'i64'), ('consensus_branch_id', 'u32'), ('sighash', '[u8; 32]'), ), diff --git a/zip_0243.py b/zip_0243.py index bd558b6..d54421a 100644 --- a/zip_0243.py +++ b/zip_0243.py @@ -163,7 +163,7 @@ def main(): 'rust_fmt': lambda x: None if x == -1 else Some(x), }), ('hash_type', 'u32'), - ('amount', 'u64'), + ('amount', 'i64'), ('consensus_branch_id', 'u32'), ('sighash', '[u8; 32]'), ), From 196c317d894bcefebbeb7aaa76778a2f246a103e Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 22 Feb 2019 22:10:57 +0000 Subject: [PATCH 3/4] Explicitly check Points against None --- sapling_generators.py | 4 ++-- sapling_jubjub.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sapling_generators.py b/sapling_generators.py index 573383d..3b22097 100644 --- a/sapling_generators.py +++ b/sapling_generators.py @@ -23,7 +23,7 @@ def group_hash(D, M): digest.update(URS) digest.update(M) p = Point.from_bytes(digest.digest()) - if not p: + if p is None: return None q = p * JUBJUB_COFACTOR if q == Point.ZERO: @@ -34,7 +34,7 @@ def find_group_hash(D, M): i = 0 while True: p = group_hash(D, M + bytes([i])) - if p: + if p is not None: return p i += 1 assert i < 256 diff --git a/sapling_jubjub.py b/sapling_jubjub.py index b8d012b..655263b 100644 --- a/sapling_jubjub.py +++ b/sapling_jubjub.py @@ -147,7 +147,7 @@ class Point(object): while True: data = rand.b(32) p = Point.from_bytes(data) - if p: + if p is not None: return p @staticmethod @@ -164,7 +164,7 @@ class Point(object): u2 = (vv - Fq.ONE) / (vv * JUBJUB_D - JUBJUB_A) u = u2.sqrt() - if not u: + if u is None: return None if u.s % 2 != u_sign: From 281dc5b0c865f7c67a1bee0c2b8fe8e6b376c01a Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 22 Feb 2019 22:16:56 +0000 Subject: [PATCH 4/4] Only generate valueBalance and bindingSig for v4+ transactions Reverts a change to the ZIP 143 test vectors caused by #9. --- transaction.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/transaction.py b/transaction.py index 39ab9b4..7a2582b 100644 --- a/transaction.py +++ b/transaction.py @@ -221,7 +221,8 @@ class Transaction(object): self.nLockTime = rand.u32() self.nExpiryHeight = rand.u32() % TX_EXPIRY_HEIGHT_THRESHOLD - self.valueBalance = rand.u64() % (MAX_MONEY + 1) + if self.nVersion >= SAPLING_TX_VERSION: + self.valueBalance = rand.u64() % (MAX_MONEY + 1) self.vShieldedSpends = [] self.vShieldedOutputs = [] @@ -239,7 +240,8 @@ class Transaction(object): self.joinSplitPubKey = rand.b(32) # Potentially invalid self.joinSplitSig = rand.b(64) # Invalid - self.bindingSig = rand.b(64) # Invalid + if self.nVersion >= SAPLING_TX_VERSION: + self.bindingSig = rand.b(64) # Invalid def header(self): return self.nVersion | (1 << 31 if self.fOverwintered else 0)