def test_SetSplitRestoreKey(): for x in range(10): maxshares = 100 thresholdList = [] # Randomly generate two digit number that ranges from 3 to 100 threshold = randint(3, 100) # Generate pair of keys in pem format pub_priKey = Nakasendo.ECKey256K1() pub_priKey2 = Nakasendo.ECKey256K1() # Retrieve the private from the PEM string privKey = pub_priKey.priKey # Sets a key from a PEM format pub_priKey2.FromPEMStr(privKey) assert str(pub_priKey) == str(pub_priKey2), "Test failed" # Split a private key into a given number of shares splitKeyList = pub_priKey2.SplitKey(threshold, maxshares) assert len(splitKeyList) == maxshares, "Test failed" for i in range(threshold): thresholdList.append(splitKeyList[i]) assert len(thresholdList) == threshold, "Test failed" # Restore a private key from a given number of shares pub_priKey2.RecoverKey(thresholdList) assert pub_priKey2.priKey == privKey, "Test failed"
def test_InitFromListHex(): for x in range(10, 20): fx = Nakasendo.BigNum().value modulo = str(randint(1000, 100000)) listCoefficients = [] for i in range(x): # Generate random coefficients for the polynomial listCoefficients.append(Nakasendo.BigNum().value) # create a Polynomial from a list of coefficients allCoeffeicient = Nakasendo.Polynomial.initFromListHex( listCoefficients) assert len(allCoeffeicient.coefficients) == x, "Test failed" # Calling evaluate polynomial function allCoeffeicient.modulo = modulo polynomial_EvaluateFX = allCoeffeicient(fx) # convert list of coefficients from string to decimal lst = [] for i in (allCoeffeicient.coefficients): lst.append(int(i, 16)) fx = int(fx, 16) modulo = int(modulo, 16) actualValue = polynomial_evaluate(lst, fx, modulo) assert polynomial_EvaluateFX.lstrip("0") == hex( actualValue).upper().lstrip("0X"), "Test failed"
def getVerifyCoefficientForPlayer(self, groupId, hiddenEvals, hiddenPolys, fromOrdinal, toOrdinal): # get the coefficients that 'from' player sent to all, where 'from' and 'to' are ordinals resCoeffEC = None multplier = toOrdinal multplierBN = Nakasendo.BigNum(str(toOrdinal), self.modulo) toOrdinalBN = Nakasendo.BigNum(str(toOrdinal), self.modulo) encryptedCoeffs = hiddenPolys[fromOrdinal] resCoeffEC = Player.getECPoint(encryptedCoeffs[0]) for coeff in encryptedCoeffs[1:]: coeffEC = Player.getECPoint(coeff) labelTimesPoints = coeffEC.multipleScalar(multplierBN) resCoeffEC = resCoeffEC + labelTimesPoints multplierBN = multplierBN * toOrdinalBN for ofOrdinal, pubPoly in hiddenEvals[fromOrdinal].items(): pubPoly = Player.getECPoint(pubPoly) if (ofOrdinal == toOrdinal): if (pubPoly == resCoeffEC): return True else: return False return False
def sign(self, groupId, message, signatureData): group = self.groups[groupId] self.ptw( "Player.sign: groupId = {0}, message = {1}, signatureData = {2}\n". format(groupId, message, signatureData)) # convert dictionary to list of points points = list(signatureData.items()) interpolator = Nakasendo.LGInterpolator \ ( points, Player.modulo, decimal=False) s_at_zero = interpolator('0') #DER format mod_bn = Nakasendo.BigNum(Player.modulo, Player.modulo) TWO = Nakasendo.BigNum('2', Player.modulo, isDec=False) modDivByTwo = mod_bn / TWO canonizedInteropolated_s = s_at_zero if (s_at_zero > modDivByTwo): canonizedInteropolated_s = mod_bn - s_at_zero DerFormatSig = Nakasendo.createDERFormat(group.signer_r, canonizedInteropolated_s) mySignature = [group.signer_r, s_at_zero] self.ptw("DER formatted signature = {0}, signature = {1}"\ .format(DerFormatSig,mySignature )) return mySignature
def DerivePubKey(Players, modulo=None, isDec=False): #Multiply the zero element by G and add them up #secretKeys = [] secret = Nakasendo.BigNum(Players[0].polynomial.coefficients[0], modulo, isDec) for i in range(1, len(Players)): secret = secret + Nakasendo.BigNum( Players[i].polynomial.coefficients[0], modulo, isDec) return secret
def HashMsg(msg, modulo=None, IsDec=False): HASHMSG = Nakasendo.hash256(msg) if (IsDec): Hm = Nakasendo.BigNum(str(int(HASHMSG.value, 16)), modulo.value, isDec=True) else: Hm = Nakasendo.BigNum(HASHMSG.value, modulo.value, isDec=False) return Hm
def __calc_matrix_sum_col(matrix, modulo=None, dec=False): vect_sum_col = [] for i in range(len(matrix[0])): bn = Nakasendo.BigNum('0', modulo, dec) bn.isDec = dec vect_sum_col.append(bn) for row_i in matrix: for j in range(len(row_i)): x_ij = Nakasendo.BigNum(row_i[j], modulo, isDec=dec) vect_sum_col[j] = vect_sum_col[j] + x_ij return vect_sum_col
def test_Sign_Verification(): msg = 'Hello, I am a message, sign me' for x in range(100): # Generate pair of keys in PEM format pub_privKey = Nakasendo.ECKey256K1() pub_key = pub_privKey.pubKey # Sign message with private Key rSig, sSig = pub_privKey.sign(msg) # Verify message's signature with public key verify_ok = Nakasendo.verify(msg, pub_key, rSig, sSig) assert verify_ok, "Test failed"
def test_SetKeyFromPem(): for x in range(10): # Generate pair of keys in pem format pub_priKey = Nakasendo.ECKey256K1() pub_priKey2 = Nakasendo.ECKey256K1() # Retrieve the private from the PEM string privKey = pub_priKey.priKey # Sets a key from a PEM format pub_priKey2.FromPEMStr(privKey) # Calculated private key should match the generated one assert str(pub_priKey) == str(pub_priKey2), "Test failed"
def test_InitFromListModuloHex(): for x in range(10, 20): modHex = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" fx = Nakasendo.BigNum().value degree = randint(10, 15) # create a random polynomial listCoefficients = Nakasendo.Polynomial.initRandomHex(degree, modHex) assert len(listCoefficients.coefficients) == (degree + 1), "Test failed" # create a Polynomial from a list of coefficient with modulo coefficientsWithModulo = Nakasendo.Polynomial.initFromListModuloHex( listCoefficients.coefficients, modHex) assert len( coefficientsWithModulo.coefficients) == degree + 1, "Test failed" # calling evaluate polynomial function polynomial_EvaluateFX = coefficientsWithModulo(fx) # convert list of coefficients from string to decimal lst = [] for i in (coefficientsWithModulo.coefficients): lst.append(int(i, 16)) fx = int(fx, 16) modulo = int(modHex, 16) actualValue = polynomial_evaluate(lst, fx, modulo) assert polynomial_EvaluateFX.lstrip("0") == hex( actualValue).upper().lstrip("0X"), "Test failed"
def test_RandomPolynomialMinMaxHex(): for x in range(10): fx = Nakasendo.BigNum().value degree = randint(10, 15) modulo = hex(randint(10000, 1000000)).lstrip("0x") min = hex(randint(10000, 10000000)).lstrip("0x") max = hex(randint(10000001, 100000000)).lstrip("0x") # create a random polynomial with range of min..max listCoefficients = Nakasendo.Polynomial.initRandomMinMaxHex( degree, modulo, min, max) assert len(listCoefficients.coefficients) == (degree + 1), "Test failed" # calling evaluate polynomial function polynomial_EvaluateFX = listCoefficients(fx) # convert list of coefficients from string to decimal lst = [] for i in (listCoefficients.coefficients): lst.append(int(i, 16)) fx = int(fx, 16) modulo = int(modulo, 16) actualValue = polynomial_evaluate(lst, fx, modulo) assert polynomial_EvaluateFX.lstrip("0") == hex( actualValue).upper().lstrip("0X"), "Test failed"
def test_RandomPolynomialFixed_a_0_Hex(): for x in range(10): fx = Nakasendo.BigNum().value degree = randint(10, 15) modulo = hex(randint(10000, 1000000)).lstrip("0x") a_0 = hex(randint(1000, 2000)).lstrip("0x").upper() # create a random polynomial with fixed a_0 listCoefficients = Nakasendo.Polynomial.initRandomFixed_a_0_Hex( degree, modulo, a_0) assert listCoefficients.coefficients[0].lstrip( "0") == a_0, "Test failed" assert len(listCoefficients.coefficients) == (degree + 1), "Test failed" # calling evaluate polynomial function polynomial_EvaluateFX = listCoefficients(fx) # convert list of coefficients from string to decimal lst = [] for i in (listCoefficients.coefficients): lst.append(int(i, 16)) fx = int(fx, 16) modulo = int(modulo, 16) actualValue = polynomial_evaluate(lst, fx, modulo) assert polynomial_EvaluateFX.lstrip("0") == hex( actualValue).upper().lstrip("0X"), "Test failed"
def test_ShareSecret(): for x in range(100): # Generate keys for alice and bob alice_pub_privKeyPEM = Nakasendo.ECKey256K1() bob_pub_privKeyPEM = Nakasendo.ECKey256K1() # alice_pubKeyPEM, alice_privKeyPEM = PyAsymKey.GenerateKeyPairPEM() # bob_pubKeyPEM, bob_privKeyPEM = PyAsymKey.GenerateKeyPairPEM() # Calculate shared secret from my private key and their public key secret_share_from_alice = alice_pub_privKeyPEM.CalculateSharedSecret( bob_pub_privKeyPEM.pubKey) secret_share_from_bob = bob_pub_privKeyPEM.CalculateSharedSecret( alice_pub_privKeyPEM.pubKey) assert secret_share_from_alice == secret_share_from_bob, "Test failed"
def createSecret(self, groupId, calcType, hiddenPolys, hiddenEvals): self.ptw("creating a secret....") group = self.groups[groupId] group.transientData.allHiddenPolynomials = hiddenPolys result = group.transientData.sumOfEvals if calcType == 'PRIVATEKEYSHARE': group.privateKeyShare = result group.publicKeyShare = group.createPublicKey() elif calcType == 'LITTLEK': group.littleK = result elif calcType == 'ALPHA': group.alpha = result else: msg = "Player:createSecret.calcType is not recognised: {0}".format( calcType) self.ptw(msg) raise PlayerError(msg) self.verificationOfHonesty(groupId, hiddenEvals, hiddenPolys) self.verifyCorrectness(groupId, hiddenEvals, hiddenPolys) # reset evals group.transientData.evalCounter = 0 group.transientData.sumOfEvals = Nakasendo.BigNum('0', Player.modulo) return groupId, result
def test_AddFromDec_HexWithBigNumApi(): for i in range(10): hexValue = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" num = int(hexValue, 16) b = str(randint(100000000, num)) c = str(randint(100000000, num)) x = Nakasendo.BigNum() y = Nakasendo.BigNum() b = Nakasendo.BigNum(b, isDec=True) c = Nakasendo.BigNum(c, isDec=True) z = y.__add__(x) a = b.__add__(c) assert z == (x + y) and a == (b + c), "Test failed"
def test_LGInterpolatorFullDec(): listTupleObj = [(2, "10"), (3, "15")] modulo = "0" dec = 1 for x in range(100, 101): randomX = randint(1000, 1000000) xValue = str(randomX) # LGInterpolator, full evaluation of the polynomial at xValue lgInterpolatorX = Nakasendo.LGInterpolator(listTupleObj, modulo, dec) lgInterpolatorX = lgInterpolatorX(xValue) TestVal = Nakasendo.BigNum(value=str(randomX * 5), mod=modulo, isDec=dec) assert lgInterpolatorX == TestVal, "Test failed"
def calculateEphemeralKey(self, groupId): group = self.groups[groupId] self.ptw("Calculating Ephemeral Key...") xfx_v = [] xfx_w = [] allOrdinals = group.allOrdinals() #allOrdinals = [] #for i in group.ordinalList : # allOrdinals.append( i[0] ) #allOrdinals.append(group.ordinal) for ord in allOrdinals: vw = group.transientData.allVWshares[ord] xfx_v.append((ord, vw[0])) point = Nakasendo.ECPoint() point.SetValue(vw[1]) w_points = point.GetAffineCoOrdinates() xfx_w.append((str(ord), w_points[0], w_points[1])) v_interpolator = Nakasendo.LGInterpolator \ ( xfx_v, Player.modulo, decimal=False) w_interpolator = Nakasendo.LGECInterpolator \ ( xfx_w, Player.modulo, decimal=False) vZeroVal = v_interpolator('0') wZeroVal = w_interpolator('0') vZeroValInv = vZeroVal.inverse() interpolated_r = wZeroVal.multipleScalar(vZeroValInv) if (interpolated_r.IsPointOnCurve() is not True): msg = ("Error in Player:calculateEphemeralKey: point not on curve") self.ptw(msg) raise PlayerError(msg) interpolated_r_points = interpolated_r.GetAffineCoOrdinates() r_bn = Nakasendo.BigNum(interpolated_r_points[0], Player.modulo) ephemeralKey = [group.littleK, r_bn] group.ephemeralKeyList.append(ephemeralKey)
def test_MultiplyByGenerator(): # Generating Random EC for x in range(10): # using the integer value of NID secp256k1, which is 714 nID = 714 # Generate a Random EC Point with default NID ==> NID_secp256k1 hexValue = Nakasendo.ECPoint(nID) bigNumB = Nakasendo.BigNum() # EC Point GetAffineCoOrdinates_GFp with default NID => NID_secp256k1 x_axis, y_axis = hexValue.GetAffineCoOrdinates() assert len(x_axis) == 62 or len(x_axis) == 64, "Test failed" # EC Point Scalar multiply on curve with supplied ID actualValue = str( Nakasendo.MultiplyByGenerator(bigNumB, compressed=True)) assert len(actualValue) == 66, "Test failed"
def test_LGInterpolatorFullHex(): listTupleObj = [(2, "A"), (3, "F")] modulo = "0" hex_value = 0 for x in range(100, 200): randomX = Nakasendo.BigNum() xValue = str(randomX.value) # LGInterpolator, full evaluation of the polynomial at xValue lgInterpolatorX = Nakasendo.LGInterpolator(listTupleObj, modulo, hex_value) lgInterpolatorX = lgInterpolatorX(xValue) TestVal = Nakasendo.BigNum(value=hex(int(randomX.value, 16) * 5).lstrip("0x").upper(), mod=modulo, isDec=hex_value) assert lgInterpolatorX == TestVal, "Test failed"
def test_CheckOnCurveFromHexOnCurve(): # Generating Random EC Points for x in range(10): # using the integer value of NID secp256k1, which is 714 nID = 714 # Generate a Random EC Point with default NID ==> NID_secp256k1 hexValue = Nakasendo.ECPoint(nID) assert hexValue.IsPointOnCurve() is True, "Test failed"
def calculateShareOfVW(self, mod): # littleK * alpha v = self.littleK * self.alpha # alpha * Generator Point GEN = Nakasendo.ECPoint() GENPOINT = GEN.GetGeneratorPoint() w = GENPOINT.multipleScalar(self.alpha) return v.value, w.value
def test_MultiplyScalarMNOnCurve(): # Generating Random EC for x in range(10): # using the integer value of NID secp256k1, which is 714 nID = 714 # Generate a Random EC Point with default NID ==> NID_secp256k1 mValue = Nakasendo.ECPoint(nID) nValue = Nakasendo.ECPoint(nID) # EC Point GetAffineCoOrdinates_GFp with default NID => NID_secp256k1 x_axis, y_axis = mValue.GetAffineCoOrdinates() assert len(x_axis) == 62 or len(x_axis) == 64, "Test failed" # EC Point Scalar multiply with supplied curve ID actualValue = str(mValue.multipltScalarEx(mValue, nValue)) # Verifying the the length of actual value as 66 assert len(actualValue) == 66, "Test failed"
def DoEncodeDecodeB58Checked(msgToEncode, encodedMsg): for x in range(1, 10): myMsgHash = Nakasendo.MessageHash(msgToEncode) encoded = myMsgHash.Base58CheckedEncode() if (encoded != encodedMsg): print('API ENCODE 58 Checked panic %s is not equal to %s' % (encoded, encodedMsg)) decoded = myMsgHash.Base58CheckedDecode(encoded) if (decoded != msgToEncode): print('API DECODE 58 Checked panic %s is not equal to %s' % (encoded, encodedMsg))
def reset(self): self.f_x = None # f(x): Polynomial evaluated for own ordinal self.evals = {} # dict ordinal:evaluated for each o in ordinallist self.sumOfEvals = \ Nakasendo.BigNum('0', self.modulo) # running total of evals self.evalCounter = 0 # counter of eval messages received from other Players self.hiddenEvals = { } # Polynomial evaluations multiplied by generator point self.hiddenPolynomial = [] # coeffs multiplied by generator point self.allHiddenPolynomials = {} self.allVWshares = {} # dict of V W shares from all players
def DoEncodeDecode(msgToEncode, encodedMsg): for x in range(1, 10): myMsgHash = Nakasendo.MessageHash(msgToEncode) encoded = myMsgHash.Base64Encode() if (encoded != encodedMsg): print('API ENCODE PANIC %s is not equal to %s' % (encoded, encodedMsg)) #print (encoded) decoded = myMsgHash.Bas64Decode(encoded) if (decoded != msgToEncode): print('API DECODE PANIC %s is not equal to %s' % (decoded, msgToEncode))
def polynomialPreCalculation(self, poly, mod, ordinal): self.transientData.reset() # evaluate polynomial for own ordinal # polynomial is set to Hex, so convert the ordinal to hex string self.transientData.f_x = poly(str(ordinal)) bignum = Nakasendo.BigNum(self.transientData.f_x, mod) self.transientData.hiddenEvals[self.ordinal] = \ str(Nakasendo.ECPoint().GetGeneratorPoint().multipleScalar(bignum)) # evaluate polynomials for the group ordinals for ord in self.ordinalList: self.transientData.evals[ord[0]] = poly(str(ord[0])) bignum = Nakasendo.BigNum(self.transientData.evals[ord[0]], mod) self.transientData.hiddenEvals[ord[0]] = \ str(Nakasendo.ECPoint().GetGeneratorPoint().multipleScalar(bignum)) # hide own polynomial using generator point GEN = Nakasendo.ECPoint() GENPOINT = GEN.GetGeneratorPoint() for index in poly.coefficients: bignum = Nakasendo.BigNum(index, mod) res = GENPOINT.multipleScalar(bignum) self.transientData.hiddenPolynomial.append(res.value)
def test_GenerateKey(): for x in range(10): # Generate a random string of fixed length String = randomString(10) # Generate a key from random generated nonce value actual_value = Nakasendo.SymEncDec(String) actual_value.GenerateKey() actual_value = actual_value.GetKey() # verifying the actual value with the expected value assert len(actual_value) == 64, "Test failed"
def test_GetAffineCoOrdinates(): # Generating Random EC for x in range(10): # using the integer value of NID secp256k1, which is 714 nID = 714 # Generate a Random EC Point with default NID ==> NID_secp256k1 hexValue = Nakasendo.ECPoint(nID) # EC Point GetAffineCoOrdinates_GFp with default NID => NID_secp256k1 x_axis, y_axis = hexValue.GetAffineCoOrdinates() assert len(x_axis) == 62 or len(x_axis) == 64, "Test failed"
def allEvalsReceived(self, groupId, toOrdinal, fromOrdinal, f_x): group = self.groups[groupId] #check toOrdinal matches own ordinal if toOrdinal != group.ordinal: msg = "allEvalsReceived toOrdinal is not correct. Received {0}, expected {1}".format \ (group.ordinal, toOrdinal) self.ptw(msg) raise PlayerError(msg) # add onto running total group.transientData.sumOfEvals += Nakasendo.BigNum(f_x, Player.modulo) # increment counter group.transientData.evalCounter += 1 if group.transientData.evalCounter != len(group.ordinalList): return False else: # last one, add on the evaluation for own ordinal group.transientData.sumOfEvals += Nakasendo.BigNum(str \ ( group.transientData.f_x), Player.modulo ) return True
def test_EncodeBase58API(test_data_dir): # Reading test data from the file with open(test_data_dir / "testData_Encode58Decode", "r") as encodeFile_txt: for x in encodeFile_txt.readlines(): encode_Value = x.split(",") # Encode given string in base58 actual_Value = Nakasendo.MessageHash(encode_Value[0]) # Verifying the actual value with expected value assert actual_Value.Base58Encode() == encode_Value[1].rstrip( "\n"), "Test failed"