import unittest import ../bncurve/groups import nimcrypto/utils type ValidationError = object of Exception proc getPoint[T: G1|G2](t: typedesc[T], data: openArray[byte]): Point[T] = when T is G1: const nextOffset = 32 var px, py: FQ else: const nextOffset = 64 var px, py: FQ2 if not px.fromBytes2(data.toOpenArray(0, nextOffset - 1)): raise newException(ValidationError, "Could not get point value") if not py.fromBytes2(data.toOpenArray(nextOffset, nextOffset * 2 - 1)): raise newException(ValidationError, "Could not get point value") if px.isZero() and py.isZero(): result = T.zero() else: var ap: AffinePoint[T] if not ap.init(px, py): raise newException(ValidationError, "Point is not on curve") result = ap.toJacobian() proc getFR(data: openArray[byte]): FR = if not result.fromBytes2(data): raise newException(ValidationError, "Could not get FR value") proc bn256ecAdd*(data: openArray[byte]): array[64, byte] = var input: array[128, byte] # Padding data let msglen = len(data) let tocopy = if msglen < 128: msglen else: 128 if tocopy > 0: copyMem(addr input[0], unsafeAddr data[0], tocopy) var p1 = G1.getPoint(input.toOpenArray(0, 63)) var p2 = G1.getPoint(input.toOpenArray(64, 127)) var apo = (p1 + p2).toAffine() if isSome(apo): let p = apo.get() # we can discard here because we supply proper buffer discard p.toBytes(result) proc bn256ecMul*(data: openArray[byte]): array[64, byte] = var input: array[96, byte] # Padding data let msglen = len(data) let tocopy = if msglen < 96: msglen else: 96 if tocopy > 0: copyMem(addr input[0], unsafeAddr data[0], tocopy) var p1 = G1.getPoint(input.toOpenArray(0, 63)) var fr = getFR(input.toOpenArray(64, 95)) var apo = (p1 * fr).toAffine() if isSome(apo): let p = apo.get() # we can discard here because we supply buffer of proper size discard p.toBytes(result) proc bn256ecPairing*(data: openArray[byte]): array[32, byte] = let msglen = len(data) if msglen mod 192 != 0: raise newException(ValidationError, "Invalid input length") if msglen == 0: # we can discard here because we supply buffer of proper size discard BNU256.one().toBytes(result) else: # Calculate number of pairing pairs let count = msglen div 192 # Pairing accumulator var acc = FQ12.one() for i in 0..