mirror of
https://github.com/monero-project/research-lab.git
synced 2024-12-22 19:49:35 +00:00
113 lines
4.1 KiB
Python
113 lines
4.1 KiB
Python
#see the aggregate schnorr pdf contained in this repository for an explanation.
|
|
import MiniNero
|
|
import MLSAG
|
|
import LLW_Sigs
|
|
import PaperWallet
|
|
import Crypto.Random.random as rand
|
|
import binascii
|
|
|
|
b = 256
|
|
q = 2**255 - 19
|
|
l = 2**252 + 27742317777372353535851937790883648493
|
|
|
|
|
|
def GenSchnorr(hash_prefix, pub, sec, k):
|
|
#modified from original algorithm to match Monero better
|
|
#see the ag schnorr pdf for original alg.
|
|
#Note in Monero, hash prefix is always 32 bytes..
|
|
#hash_prefix = binascii.hexlify(prefix)
|
|
#k = PaperWallet.skGen() #comment for testing
|
|
comm = MiniNero.scalarmultBase(k)
|
|
print("comm", "hash_prefix", comm, hash_prefix)
|
|
if MiniNero.scalarmultBase(sec) != pub:
|
|
print"error in genSchnorr"
|
|
return -1
|
|
if MiniNero.sc_check(sec) == False:
|
|
print "fail in geSchnorr"
|
|
return -1
|
|
c = MiniNero.sc_reduce_key(MiniNero.cn_fast_hash(hash_prefix + pub + comm))
|
|
r = MiniNero.sc_sub_keys(k, MiniNero.sc_mul_keys(c, sec))
|
|
#uncomment to test malleability
|
|
c = MiniNero.sc_reduce_key(MiniNero.cn_fast_hash(hash_prefix + pub + comm))
|
|
r = MiniNero.sc_unreduce_key(MiniNero.sc_sub_keys(k, MiniNero.sc_mul_keys(c, sec)))
|
|
|
|
return r, c
|
|
|
|
def VerSchnorr(hash_prefix, pub, r, c):
|
|
#hash_prefix = binascii.hexlify(prefix)
|
|
check1 = MiniNero.toPoint(pub)
|
|
comm = MiniNero.addKeys(MiniNero.scalarmultKey(pub,c), MiniNero.scalarmultBase(r))
|
|
c2 = MiniNero.cn_fast_hash(hash_prefix + pub + comm)
|
|
print(MiniNero.sc_sub_keys(c, c2) == "0000000000000000000000000000000000000000000000000000000000000000")
|
|
return (MiniNero.sc_sub_keys(c, c2) == "0000000000000000000000000000000000000000000000000000000000000000")
|
|
|
|
def GenSchnorrNonLinkable(x, P1, P2, index):
|
|
if index == 0:
|
|
a = PaperWallet.skGen()
|
|
L1 = MiniNero.scalarmultBase(a)
|
|
s2 = PaperWallet.skGen()
|
|
c2 = MiniNero.cn_fast_hash(L1)
|
|
L2 = MiniNero.addKeys(MiniNero.scalarmultBase(s2), MiniNero.scalarmultKey(P2, c2))
|
|
c1 = MiniNero.cn_fast_hash(L2)
|
|
s1 = MiniNero.sc_mulsub_keys(a, x, c1)
|
|
if index == 1:
|
|
a = PaperWallet.skGen()
|
|
L2 = MiniNero.scalarmultBase(a)
|
|
s1 = PaperWallet.skGen()
|
|
c1 = MiniNero.cn_fast_hash(L2)
|
|
L1 = MiniNero.addKeys(MiniNero.scalarmultBase(s1), MiniNero.scalarmultKey(P1, c1))
|
|
c2 = MiniNero.cn_fast_hash(L1)
|
|
s2 = MiniNero.sc_mulsub_keys(a, x, c2)
|
|
return L1, s1, s2,
|
|
|
|
def VerSchnorrNonLinkable(P1, P2, L1, s1, s2):
|
|
c2 = MiniNero.cn_fast_hash(L1)
|
|
L2 = MiniNero.addKeys(MiniNero.scalarmultBase(s2), MiniNero.scalarmultKey(P2, c2))
|
|
c1 = MiniNero.cn_fast_hash(L2)
|
|
L1p = MiniNero.addKeys(MiniNero.scalarmultBase(s1), MiniNero.scalarmultKey(P1, c1))
|
|
if L1 == L1p:
|
|
print"Verified"
|
|
return 0
|
|
else:
|
|
print "Didn't verify"
|
|
print(L1,"!=", L1p)
|
|
return -1
|
|
|
|
|
|
|
|
def GenASNL(x, P1, P2, indices):
|
|
#Aggregate Schnorr Non-Linkable
|
|
#x, P1, P2, are key vectors here, but actually you
|
|
#indices specifices which column of the given row of the key vector you sign.
|
|
#the key vector with the first or second key
|
|
n = len(x)
|
|
print("Generating Aggregate Schnorr Non-linkable Ring Signature")
|
|
L1 = [None] * n
|
|
s1 = [None] * n
|
|
s2 = [None] * n
|
|
s = MiniNero.intToHex(0)
|
|
for j in range(0, n):
|
|
L1[j], s1[j], s2[j] = GenSchnorrNonLinkable(x[j], P1[j], P2[j], indices[j])
|
|
s = MiniNero.sc_add_keys(s, s1[j])
|
|
return L1, s2, s
|
|
|
|
def VerASNL(P1, P2, L1, s2, s):
|
|
#Aggregate Schnorr Non-Linkable
|
|
print("Verifying Aggregate Schnorr Non-linkable Ring Signature")
|
|
n = len(P1)
|
|
LHS = MiniNero.scalarmultBase(MiniNero.intToHex(0))
|
|
RHS = MiniNero.scalarmultBase(s)
|
|
for j in range(0, n):
|
|
c2 = MiniNero.cn_fast_hash(L1[j])
|
|
L2 = MiniNero.addKeys(MiniNero.scalarmultBase(s2[j]), MiniNero.scalarmultKey(P2[j], c2))
|
|
LHS = MiniNero.addKeys(LHS, L1[j])
|
|
c1 = MiniNero.cn_fast_hash(L2)
|
|
RHS = MiniNero.addKeys(RHS, MiniNero.scalarmultKey(P1[j], c1))
|
|
if LHS == RHS:
|
|
print"Verified"
|
|
return 0
|
|
else:
|
|
print "Didn't verify"
|
|
print(LHS,"!=", RHS)
|
|
return -1
|
|
|