Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 222 additions & 0 deletions src/embit/silent_payments/dleq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
"""
BIP-374 DLEQ (Discrete Log Equality Proofs).

Given points A = a*G and C = a*B, proves knowledge of scalar a
across both bases (G and B) without revealing a.

Spec: https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki
Reference: https://github.com/bitcoin/bips/blob/master/bip-0374/reference.py
"""

from .. import hashes
from ..util.key import SECP256K1_ORDER, SECP256K1_G
from ..util.secp256k1 import (
ec_pubkey_create,
ec_pubkey_parse,
ec_pubkey_serialize,
ec_pubkey_tweak_mul,
ec_pubkey_combine,
EC_COMPRESSED,
)

_G_COMPRESSED = b"\x02" + SECP256K1_G[0].to_bytes(32, "big")
DLEQ_TAG_AUX = "BIP0374/aux"
DLEQ_TAG_NONCE = "BIP0374/nonce"
DLEQ_TAG_CHALLENGE = "BIP0374/challenge"


class DLEQError(Exception):
"""Raised when DLEQ proof generation fails due to invalid inputs."""


def _scalar_mult_G(scalar_bytes, G_sec):
"""Return scalar * G_sec as an opaque pubkey handle.

Uses ec_pubkey_create for the standard secp256k1 generator (fast path)
and parse + tweak_mul for an arbitrary base point.
Raises ValueError / OverflowError on invalid inputs.
"""
if G_sec == _G_COMPRESSED:
return ec_pubkey_create(scalar_bytes)
pub = ec_pubkey_parse(G_sec)
ec_pubkey_tweak_mul(pub, scalar_bytes)
return pub


def generate_dleq_proof(a_bytes, B_sec, r=None, m=None, G=None):
"""
Generate a 64-byte DLEQ proof (BIP-374 GenerateProof).

Proves log_G(A) == log_B(C) without revealing scalar a,
where A = a*G and C = a*B.

Args:
a_bytes: 32-byte private key scalar.
B_sec: 33-byte compressed pubkey (alternative base point B).
r: 32-byte auxiliary randomness. Must be fresh per proof; reusing r
with the same (a, B) and no m can leak a. When m is provided,
it is mixed into nonce generation, so that leak does not occur
if the reused r is paired with different messages, but fresh r
is still required.
G: Optional 33-byte compressed base point. Defaults to secp256k1 G.
BIP-374 footnote 2 allows any curve point as the generator so
the algorithm can be used with alternate bases on secp256k1.

Returns:
64-byte proof: bytes(32, e) || bytes(32, s).

Raises:
DLEQError: on invalid inputs or internal self-verification failure.
"""
if len(a_bytes) != 32:
raise DLEQError("a_bytes must be 32 bytes")
if len(B_sec) != 33:
raise DLEQError("B_sec must be a 33-byte compressed pubkey")
if m is not None and len(m) != 32:
raise DLEQError("m must be exactly 32 bytes per BIP-374")
if G is not None and len(G) != 33:
raise DLEQError("G must be a 33-byte compressed pubkey")

G_sec = _G_COMPRESSED if G is None else G

a_int = int.from_bytes(a_bytes, "big")
if a_int == 0 or a_int >= SECP256K1_ORDER:
raise DLEQError("a is out of range [1, n-1]")

try:
A_internal = _scalar_mult_G(a_bytes, G_sec) # A = a*G
except (ValueError, OverflowError):
raise DLEQError("Invalid private key or G point")
A_compressed = ec_pubkey_serialize(A_internal, EC_COMPRESSED)

# C = a*B; ec_pubkey_parse rejects the point at infinity (spec is_infinite(B)).
try:
C_internal = ec_pubkey_parse(B_sec)
ec_pubkey_tweak_mul(C_internal, a_bytes)
except (ValueError, OverflowError):
raise DLEQError("Invalid B_sec")
C_compressed = ec_pubkey_serialize(C_internal, EC_COMPRESSED)

if r is None:
raise DLEQError(
"r must be provided: pass 32 bytes of fresh auxiliary randomness"
)
if len(r) != 32:
raise DLEQError("r must be 32 bytes")

aux_hash = hashes.tagged_hash(DLEQ_TAG_AUX, r)
t_int = a_int ^ int.from_bytes(aux_hash, "big")
t = t_int.to_bytes(32, "big")

m_prime = m if m is not None else b""

# k = H_nonce(t || cbytes(A) || cbytes(C) || m') mod n
rand = hashes.tagged_hash(DLEQ_TAG_NONCE, t + A_compressed + C_compressed + m_prime)
k = int.from_bytes(rand, "big") % SECP256K1_ORDER
if k == 0:
raise DLEQError("Derived nonce k is zero")

k_bytes = k.to_bytes(32, "big")

R1_internal = _scalar_mult_G(k_bytes, G_sec) # R1 = k*G
R1_compressed = ec_pubkey_serialize(R1_internal, EC_COMPRESSED)

R2_internal = ec_pubkey_parse(B_sec) # R2 = k*B (fresh buffer)
ec_pubkey_tweak_mul(R2_internal, k_bytes)
R2_compressed = ec_pubkey_serialize(R2_internal, EC_COMPRESSED)

# e = int(H_challenge(A || B || C || G || R1 || R2 || m'))
e_hash = hashes.tagged_hash(
DLEQ_TAG_CHALLENGE,
A_compressed
+ B_sec
+ C_compressed
+ G_sec
+ R1_compressed
+ R2_compressed
+ m_prime,
)
e = int.from_bytes(e_hash, "big")

s = (k + e * a_int) % SECP256K1_ORDER

proof = e.to_bytes(32, "big") + s.to_bytes(32, "big")

# self-verify before returning (as required by spec)
if not verify_dleq_proof(A_compressed, B_sec, C_compressed, proof, m, G=G):
raise DLEQError("Self-verification of generated proof failed")

return proof


def verify_dleq_proof(A_sec, B_sec, C_sec, proof, m=None, G=None):
"""
Verify a 64-byte DLEQ proof (BIP-374 VerifyProof).

Returns True if the proof is valid, False otherwise.
Never raises exceptions — all failures return False.

Args:
A_sec: 33-byte compressed pubkey (a*G).
B_sec: 33-byte compressed pubkey (alternative base point B).
C_sec: 33-byte compressed pubkey (a*B, the ECDH result).
proof: 64-byte proof bytes.
m: Optional 32-byte message that was bound during generation.
G: 33-byte compressed base point. Defaults to secp256k1 G.
Must match the G used during proof generation.
"""
if len(proof) != 64:
return False
if m is not None and len(m) != 32:
return False

G_sec = _G_COMPRESSED if G is None else G

try:
e = int.from_bytes(proof[:32], "big")
s = int.from_bytes(proof[32:], "big")

if s >= SECP256K1_ORDER:
return False

neg_e = (-e) % SECP256K1_ORDER
if neg_e == 0:
return False

m_prime = m if m is not None else b""
s_bytes = s.to_bytes(32, "big")
neg_e_bytes = neg_e.to_bytes(32, "big")

# ec_pubkey_parse rejects the point at infinity (spec is_infinite checks
# for A, B, C). ec_pubkey_combine raises ValueError when R1 or R2 would
# be the point at infinity (spec is_infinite(R1) / is_infinite(R2)).
# ec_pubkey_tweak_mul mutates in-place; each point gets a fresh buffer.

# R1 = s*G + (-e)*A
sG_internal = _scalar_mult_G(s_bytes, G_sec)
neg_eA_internal = ec_pubkey_parse(A_sec)
ec_pubkey_tweak_mul(neg_eA_internal, neg_e_bytes)
R1_internal = ec_pubkey_combine(sG_internal, neg_eA_internal)
R1_compressed = ec_pubkey_serialize(R1_internal, EC_COMPRESSED)

# R2 = s*B + (-e)*C
sB_internal = ec_pubkey_parse(B_sec)
ec_pubkey_tweak_mul(sB_internal, s_bytes)
neg_eC_internal = ec_pubkey_parse(C_sec)
ec_pubkey_tweak_mul(neg_eC_internal, neg_e_bytes)
R2_internal = ec_pubkey_combine(sB_internal, neg_eC_internal)
R2_compressed = ec_pubkey_serialize(R2_internal, EC_COMPRESSED)

# Recompute e' = int(H_challenge(A || B || C || G || R1 || R2 || m'))
e_check = int.from_bytes(
hashes.tagged_hash(
DLEQ_TAG_CHALLENGE,
A_sec + B_sec + C_sec + G_sec + R1_compressed + R2_compressed + m_prime,
),
"big",
)

return e == e_check

except (ValueError, OverflowError):
return False
12 changes: 12 additions & 0 deletions tests/tests/data/test_vectors_generate_proof.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
index,point_G,scalar_a,point_B,auxrand_r,message,result_proof,comment
0,02cef38f55e78b321a1f785cb1c6e33dfcef9784c18bdc4e279801c449ccdfb88e,07ff93d43f1012a5d4a44aba55240212ed39c87b3344e46757d99f24177fc576,02dad4b35c2379ba8334c9a5dda8f6e6d5cd575a7cc9d3ca4faaac51839daaa30f,cb979b0fc8ccc7f237751e719d992fcc324b6500af33999cd54a3e5c05fb1ea4,efb07d4b382d3da1079fbf24df623ba6c2e4c764993bbfa6dd7a4fe4aaf33859,7e7e934169e0bf4706e6b29e5a621c7fe199a524744a25af80071e111c0e2e94118e730d8add118dd2ee4f7d1cc183e1b87168362d1a6f85c16d8671a3fc7a8a,Success case 1
1,02464e351831efedb755223cabbf664f10564b4742c725c023034bc928ed339e0e,f4e9172285393c6ada994c811b3e50fc47e96421ea7e54f4a4e459528d4cf562,03fe589b0fa23f060f6d4d1e76b9b19d5bb3db0e56d39a4303913de0e706463008,75f12482b9209dae12230ea1f8bf69723a1b447d361db8f510dd9ab33556fd4c,76184ce9eea5b339ebf5304b57452c1ada1466610f0a58574d6c496798cee04b,6b4521a8363a7ebc5d95ac6ec6b64db81fcf21795187d7c4600c42b73fb4fb9870ab8d106c0fd2d292c1710e10437b20575ddb3cb32eb77a5618d94ddba600f2,Success case 2
2,0222db2054fef98344352a13bc0304a71da7b5e9a2f7fd1f3c9f3519a3d9377fb7,589476913e763b60d5c2a5bfb39230ec669caac1b44312e9bcd2d3f4473abfef,03bc7a19970c812118f74ba659b491e00dade6096ff62d1afe032a92b8671498ed,4da1c4c4b0f9db4eb6b2e5cb648d7e8a0aa35aa5c4ec4d07f096e0e03deca366,66503623468a78cfcef47888c85e0010ecd897f441d263448bfc7a89b882ab20,12aa2aa469b3c037871a09d18ab18d3840219b1ed169f6ef9deae6d927949884a459705ae89a57522224ce3482dee00a41ba511188ae60efdeb736223eb66e7b,Success case 3
3,03dfa65bd3711eba75fa1996a0c1d95a4419bd835304152d9aa6efa590670f2af6,24d0ed3fc189eb1b64e5dc9dd4af0f3c8c143b0c79cb5fcca0dfa08a11cc60a1,03b51081323d38fb0b75f0c1ec6755fdb79c239c327ca11269fe68ba8a878b704e,31a68d6db27f6404bbceff646ff1b26a34704a0105a36c5a845d0257cea19c9b,f2996b3766d123a949e65541baf1d89d446360d05af51bd93f0445d8c472c952,7907653d29c5722ae44510e7f2839f253450aefc833b7e0a3b38384032f847f2cf41136b2fe6a558ad125287d20c0117f2a30c4ac0c4cebbcfa1dd3a69d84200,Success case 4
4,02b15de5a3aefcfe2473916c76e619b5800ac7250ef93a9e6e0dd1505104fc58e7,73fffa796edb72d111b5e0bbda1608f098ac98120796f971b438691e1bfb7b96,03a4692be176ff89a972de9cc407083096847b950d1cae72b947665a3d5f4c2f01,1cdfb4d7cce5e50783299896a471a44e6aa2c5e2100d6c37987c6b40503c6162,0ceb45f560f2cf6b76a139ffe2c47c5ca6d26d6a3a210e59f197413bbec040b4,02277ca5a7acfe8ae13c2db4a8f74489d0ba100ed8b082381ddb6522c4510718ab88b8dbbd785c388ade79586cf6416f3c47a79670af84abccc788a5d9f2e327,Success case 5
5,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,c08ca8e0bb59769fc6a4e078456284e00ea34f65add988c246e1bba85824ccdc,034bccb1c570ac1f3bc42d61fe35de605b99626501ccb20297e1acbbf2d7152aa1,c8d7056abd4726eb5a0f198740af14d6c1f0c16e5d7a37eaec621b661e669ac4,,503562d36910cd2d61a4d07c8ff680265c713e63dde0dcb88e6ea3c58597bdc05b86db9af95eccc475ce2177f941c118fefed20227d4ce8ce9557cb008758de6,Success case 6
6,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,8e641ba6bf7f64eec76005a29585a5035376375f33e331215aedfe03b8e80e7a,0231c64e3efa506fdad6aad0f6084d5f6739de7f448d7e66f9d22f842638f41d60,02a7b2e2f5a5e9b1078dbb160502a32491fe80a091e91dd92cf77b0b7d90970f,35841ca532846e1cdd23a3d107824343584f88eff580929469865eae8355ee3c,5c7b27a33210750e9de8679d9f43497cf9f12ac642cde0a1fc26443aa2fc89bf71aabf7bac89f5d8a96cbe86daba155fa74d6f3e111136179e53b04eb6d7807f,Success case 7
7,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,cfb9a7ecc49bea4f2e2ee34c38a6f48b5cd5bd06f4e4d4ffb45905b3d26db842,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,d38466b77484154a3fcb3151094c1c8a845c73a3c036b3a8ebffd8ef62c9047f,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,Success case 8
8,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,0000000000000000000000000000000000000000000000000000000000000000,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,d38466b77484154a3fcb3151094c1c8a845c73a3c036b3a8ebffd8ef62c9047f,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,INVALID,Failure case (a=0)
9,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,d38466b77484154a3fcb3151094c1c8a845c73a3c036b3a8ebffd8ef62c9047f,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,INVALID,Failure case (a=N [group order])
10,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,cfb9a7ecc49bea4f2e2ee34c38a6f48b5cd5bd06f4e4d4ffb45905b3d26db842,INFINITY,d38466b77484154a3fcb3151094c1c8a845c73a3c036b3a8ebffd8ef62c9047f,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,INVALID,Failure case (B is point at infinity)
16 changes: 16 additions & 0 deletions tests/tests/data/test_vectors_verify_proof.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
index,point_G,point_A,point_B,point_C,proof,message,result_success,comment
0,02cef38f55e78b321a1f785cb1c6e33dfcef9784c18bdc4e279801c449ccdfb88e,02b540b22c2c5ef0dc886abdaad27498453d893265560bc08a187319af6f845f58,02dad4b35c2379ba8334c9a5dda8f6e6d5cd575a7cc9d3ca4faaac51839daaa30f,03fefe00951dcd0ef10b12523393c2b8113119de4fdeeab320694e96bdccd2775b,7e7e934169e0bf4706e6b29e5a621c7fe199a524744a25af80071e111c0e2e94118e730d8add118dd2ee4f7d1cc183e1b87168362d1a6f85c16d8671a3fc7a8a,efb07d4b382d3da1079fbf24df623ba6c2e4c764993bbfa6dd7a4fe4aaf33859,TRUE,Success case 1
1,02464e351831efedb755223cabbf664f10564b4742c725c023034bc928ed339e0e,032baaf1b10845a51b551196984a91efe2adf9d41b92bec3927218e6e4ca344002,03fe589b0fa23f060f6d4d1e76b9b19d5bb3db0e56d39a4303913de0e706463008,031f59aa1df22190e00380d8c5941adf899f596593765a1251005fd24f2bf7c884,6b4521a8363a7ebc5d95ac6ec6b64db81fcf21795187d7c4600c42b73fb4fb9870ab8d106c0fd2d292c1710e10437b20575ddb3cb32eb77a5618d94ddba600f2,76184ce9eea5b339ebf5304b57452c1ada1466610f0a58574d6c496798cee04b,TRUE,Success case 2
2,0222db2054fef98344352a13bc0304a71da7b5e9a2f7fd1f3c9f3519a3d9377fb7,026aa26fcd626f8f55295859e9f8dd1f103149dd64d77c2bbba1bcf33bb37ebaa2,03bc7a19970c812118f74ba659b491e00dade6096ff62d1afe032a92b8671498ed,035628d1a69910daef614c7cae68d71ece55c5908af2360629e25c1b7de21eeb4b,12aa2aa469b3c037871a09d18ab18d3840219b1ed169f6ef9deae6d927949884a459705ae89a57522224ce3482dee00a41ba511188ae60efdeb736223eb66e7b,66503623468a78cfcef47888c85e0010ecd897f441d263448bfc7a89b882ab20,TRUE,Success case 3
3,03dfa65bd3711eba75fa1996a0c1d95a4419bd835304152d9aa6efa590670f2af6,031bf61ba89009ee1266c9003a72e8e07d77877678ccda7f15325aadcd64ed186b,03b51081323d38fb0b75f0c1ec6755fdb79c239c327ca11269fe68ba8a878b704e,02d1b1f37a80217ba73785babfa63251052775f9d3ca65060054033288b7a3f66b,7907653d29c5722ae44510e7f2839f253450aefc833b7e0a3b38384032f847f2cf41136b2fe6a558ad125287d20c0117f2a30c4ac0c4cebbcfa1dd3a69d84200,f2996b3766d123a949e65541baf1d89d446360d05af51bd93f0445d8c472c952,TRUE,Success case 4
4,02b15de5a3aefcfe2473916c76e619b5800ac7250ef93a9e6e0dd1505104fc58e7,0296c8e00dda60bb5565b77371ff913091978646b58ccf218bc591f68a75232e6e,03a4692be176ff89a972de9cc407083096847b950d1cae72b947665a3d5f4c2f01,03a7a7f9527fd387c2b2ce0c76669d646c78a3b470a4b34d3a2dabafc8505ef472,02277ca5a7acfe8ae13c2db4a8f74489d0ba100ed8b082381ddb6522c4510718ab88b8dbbd785c388ade79586cf6416f3c47a79670af84abccc788a5d9f2e327,0ceb45f560f2cf6b76a139ffe2c47c5ca6d26d6a3a210e59f197413bbec040b4,TRUE,Success case 5
5,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,02637b2c3ea8ca80b9caecc50f4134c86ae9cf7a269133e7afc71f30e3a3cda60c,034bccb1c570ac1f3bc42d61fe35de605b99626501ccb20297e1acbbf2d7152aa1,0285b826c8dd175805901906b6c9b4140a30cbcc94c6e7dcf36476038bf90d4718,503562d36910cd2d61a4d07c8ff680265c713e63dde0dcb88e6ea3c58597bdc05b86db9af95eccc475ce2177f941c118fefed20227d4ce8ce9557cb008758de6,,TRUE,Success case 6
6,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,02983a72b4cb44d4322641a7b2001900cd6ae0908a610546c73ed126accdba0514,0231c64e3efa506fdad6aad0f6084d5f6739de7f448d7e66f9d22f842638f41d60,03af1bc14b384eda28398df6a7900e567c5b6f6613cafce5027b98be015286f71b,5c7b27a33210750e9de8679d9f43497cf9f12ac642cde0a1fc26443aa2fc89bf71aabf7bac89f5d8a96cbe86daba155fa74d6f3e111136179e53b04eb6d7807f,35841ca532846e1cdd23a3d107824343584f88eff580929469865eae8355ee3c,TRUE,Success case 7
7,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,TRUE,Success case 8
8,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 1
9,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 2
10,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 3
11,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 4
12,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Swapped points case 5
13,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,78a5544afa75bf152653fe55fb76926f2f65131ff090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb2d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Tampered proof (random bit-flip)
14,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,03611410561c35dae13135e4ad8094baac9bbcf2f4e18498181a8ff8a6d43be9d9,021cb81121a00f89769903305a367ad3cc02d5b402b12c026e06ac94bde28cd608,03d9a98624c0c74fc7eebd39ed84175f80d03c774908e75ca737a0745d1c64e20a,78a5544afa75bf152653fe55fb76926f2f65131bf090972a0b0b37d310c28a6bde0e7bfacc10ac12d36f55316ba134b6ba0b844a65ae05cad53c0b296c6639bb,22616bb5fb6d7c68270f305122f2a09e833239c4b1c9a04e285119fb606ac794,FALSE,Tampered message (random bit-flip)
Loading
Loading