A ring signature is a digital signature that is created by a member of a group that each have their own keys. With this, it will not be possible to determine the person in the group who has created the signature. They were initially created by Ron Rivest, Adi Shamir, and Yael Tauman in 2001. With the Borromean Ring signer method, we can create a number of rings and then sign a message with one of the private keys on each of the rings. In this case, we will create one ring with three keys and another ring with three keys, and we will then sign with one key from each ring. This should be verified. We will then replace one of the private keys so that there will be no public key on the rings, and which should negatively verify.
Borromean Ring signer |
Theory
Code
The code used is:
import sys from ecpy.curves import Curve from ecpy.keys import ECPrivateKey import borromean import binascii import secrets m1 = 'Hello' if (len(sys.argv)>1): m1=str(sys.argv[1]) print ("Message: ",m1) m1=m1.encode() cv = Curve.get_curve('secp256k1') seckey0 = ECPrivateKey(secrets.randbits(32*8), cv) seckey1 = ECPrivateKey(secrets.randbits(32*8), cv) seckey2 = ECPrivateKey(secrets.randbits(32*8), cv) seckey3 = ECPrivateKey(secrets.randbits(32*8), cv) seckey4 = ECPrivateKey(secrets.randbits(32*8), cv) seckey5 = ECPrivateKey(secrets.randbits(32*8), cv) pubkey0 = seckey0.get_public_key() pubkey1 = seckey1.get_public_key() pubkey2 = seckey2.get_public_key() pubkey3 = seckey3.get_public_key() pubkey4 = seckey4.get_public_key() pubkey5 = seckey5.get_public_key() print(f"Key ring 1: secret keys: {seckey0.d},{seckey1.d},{seckey2.d}") print(f"Key ring 2: secret keys: {seckey3.d},{seckey4.d},{seckey5.d}") borromean = borromean.Borromean() pubring1 = [pubkey0, pubkey1, pubkey2] pubring2 = [pubkey3, pubkey4, pubkey5] secring1 = [seckey0, seckey1, seckey2] secring2 = [seckey3, seckey4, seckey5] s1=1 s2=1 pubset = (pubring1 , pubring2) secset = [secring1[s1] , secring2[s2]] secidx = [s1,s2] sigma = borromean.sign(m1, pubset, secset, secidx ) print ("\ne0=",binascii.hexlify(sigma[0])) print ("Signature (s):") for s in sigma[1]: print (binascii.hexlify(s)) rtn=borromean.verify( m1, sigma, pubset) print ("\nChecking with valid key (Key 2 in Ring 1, Key 2 in Ring 2: ",rtn) seckey1 = ECPrivateKey(secrets.randbits(32*8), cv) pubring1 = [pubkey0, pubkey1, pubkey2] pubring2 = [pubkey3, pubkey4, pubkey5] secring1 = [seckey0, seckey1, seckey2] secring2 = [seckey3, seckey4, seckey5] s1=1 # seckey1 wrong for pubkey1 s2=1 # seckey3 okay for pubkey3 pubset = (pubring1 , pubring2) secset = [secring1[s1] , secring2[s2]] secidx = [s1,s2] sigma = borromean.sign(m1, pubset, secset, secidx ) rtn=borromean.verify(m1, sigma, pubset) print ("Checking with non-valid key (Key 2 in Ring 1) and valid Key 2 in Ring 2: ",rtn)
A sample run:
Message: Hello Key ring 1: secret keys: 29875636843252127507955771140493761058745571354380727422781883818399443737006,97218495476827164225347692618071712330690381390998678394112169358916634197973,115676391249222958503558958505064309953121480304377021022672178145871691693856 Key ring 2: secret keys: 23755527786469626298119838665469887802365884775146742464420183004417306811346,37301517688390233590722677956221422785988140595590490774518256329076480299102,97160227373003091865407598081510266465466948946312479036443319324502948855317 e0= b'd0551fa12507e4338e9fe1460dcae7ee09e769857c615b08dee8fc3b7eba11cd' Signature (s): b'53a5f4657992ff875fc5a9bc23f682fed5e9f8d8b5150882ef8a0b884959e564' b'2df3bde7e1e142491d06e71988fa56fceded189b3620be13f9fdbf18f1eaf42e' b'b5cb16690e7d096a3e774319796d369a5a01f0a69dfbb93b55d38a3729620522' b'5c135236bbba5ef39aad2d7db19535df384eac5c038ae310140abfeb1386e889' b'b86d0352a7c4b6ab044522625ec0914862f69b0ea5370eebf7715ba10fa61267' b'30937a6fc60b0cc2eb558dfc52fbf890bd1fd1a4c18030108f2af5e4b9834f89' Checking with valid key (Key 2 in Ring 1, Key 2 in Ring 2: True Checking with non-valid key (Key 2 in Ring 1) and valid Key 2 in Ring 2: False Verified!
Reference
[1] Maxwell, G., & Poelstra, A. (2015). Borromean ring signatures. Accessed: Jun, 8, 2019. [paper]