diff --git a/contents/cap-tbd/definitions_and_implementation_notes.md b/contents/cap-tbd/definitions_and_implementation_notes.md new file mode 100644 index 000000000..9868d0a9d --- /dev/null +++ b/contents/cap-tbd/definitions_and_implementation_notes.md @@ -0,0 +1,69 @@ +## Curve Definition +BLS12 curve is fully defined by the following set of parameters (coefficient A=0 for all BLS12 curves): + +``` +Base field modulus = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab +B coefficient = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 +Main subgroup order = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 +Extension tower +Fp2 construction: +Fp quadratic non-residue = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa +Fp6/Fp12 construction: +Fp2 cubic non-residue c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +Fp2 cubic non-residue c1 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +Twist parameters: +Twist type: M +B coefficient for twist c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 +B coefficient for twist c1 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 +Generators: +G1: +X = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb +Y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1 +G2: +X c0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8 +X c1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e +Y c0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801 +Y c1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be +Pairing parameters: +|x| (miller loop scalar) = 0xd201000000010000 +x is negative = true +``` +One should note that base field modulus is equal to 3 mod 4 that allows an efficient square root extraction. + + +## Notes of Encoding +### Field Elements +For elements of the quadratic extension field (Fp2) encoding is byte concatenation of individual encoding of the coefficients totaling in 128 bytes for a total encoding. For an Fp2 element in a form el = c0 + c1 * v where v is formal quadratic non-residue and c0 and c1 are Fp elements the corresponding byte encoding will be encode(c0) || encode(c1) where || means byte concatenation. + +Note on the top 16 bytes being zero: it’s required that the encoded element is “in a field” that means strictly < modulus. In BigEndian encoding it automatically means that for a modulus that is just 381 bit long top 16 bytes in 64 bytes encoding are zeroes and it must be checked if only a subslice of input data is used for actual decoding. + +If encodings do not follow this spec anywhere during parsing in the precompile the precompile must return an error. + +### Point of infinity +Also referred to as “zero point”. For BLS12 curves point with coordinates (0, 0) (formal zeroes in Fp or Fp2) is not on the curve, so encoding of such point (0, 0) is used as a convention to encode point of infinity. + + ### Behavior on empty inputs +Certain operations have variable length input, such as multiexponentiations (takes a list of pairs (point, scalar)), or pairing (takes a list of (G1, G2) points). While their behavior is well-defined (from arithmetic perspective) on empty inputs, this proposal discourages such use cases and variable input length operations must return an error if input is empty. + + +## Field Element to Curve Mapping +See linked [document](https://github.com/namankumar/stellar-protocol/blob/master/contents/cap-tbd/field_element_to_curve_point_mapping.md). + + + +## Test Cases +Due to the large test parameters space we first provide properties that various operations must satisfy. We use additive notation for point operations, capital letters (P, Q) for points, small letters (a, b) for scalars. Generator for G1 is labeled as G, generator for G2 is labeled as H, otherwise we assume random point on a curve in a correct subgroup. 0 means either scalar zero or point of infinity. 1 means either scalar one or multiplicative identity. group_order is a main subgroup order. e(P, Q) means pairing operation where P is in G1, Q is in G2. + +Required properties for basic ops (add/multiply): + +- Commutativity: P + Q = Q + P +- Additive negation: P + (-P) = 0 +- Doubling P + P = 2*P +- Subgroup check: group_order * P = 0 +- Trivial multiplication check: 1 * P = P +- Multiplication by zero: 0 * P = 0 +- Multiplication by the unnormalized scalar (scalar + group_order) * P = scalar * P +- Required properties for pairing operation: + +Degeneracy e(P, 0*Q) = e(0*P, Q) = 1 +Bilinearity e(a*P, b*Q) = e(a*b*P, Q) = e(P, a*b*Q) (internal test, not visible through ABI) diff --git a/contents/cap-tbd/field_element_to_curve_point_mapping.md b/contents/cap-tbd/field_element_to_curve_point_mapping.md new file mode 100644 index 000000000..36be448cf --- /dev/null +++ b/contents/cap-tbd/field_element_to_curve_point_mapping.md @@ -0,0 +1,244 @@ +# Field element to curve point mapping + +For a BLS12-381 a short Weierstrass curve equation y^2 = x^3 + A * x + B has a property that a product AB = 0, so to implement a mapping function two step algorithms is performed: +- Field element is mapped to a some other curve with AB != 0 +- Isogeny is applied to one to one map a point of this other curve to a point on BLS12-381 +- Cofactor is cleared for a point now on BLS12-381 + +Below we describe generic algorithms for mapping and isogeny application, and later on give concrete parameters for the algorithms + +## Helper function to clear a cofactor + +Later on we use a helper function to clear a cofactor of the curve point. It's implemented as + +~~~ + clear_cofactor(P) := h_eff * P +~~~ + +where values of h_eff are given below in parameters sections + +## Simplified SWU for AB != 0 + +The function map\_to\_curve\_simple\_swu(u) implements a simplification +of the Shallue-van de Woestijne-Ulas mapping described by Brier et +al., which they call the "simplified SWU" map. Wahby and Boneh generalize and optimize this mapping. + +Preconditions: A Weierstrass curve y^2 = g(x) x^3 + A * x + B where A != 0 and B != 0. + +Constants: + +- A and B, the parameters of the Weierstrass curve. + +- Z, an element of F meeting the below criteria. + The criteria are: + 1. Z is non-square in F, + 2. Z != -1 in F, + 3. the polynomial g(x) - Z is irreducible over F, and + 4. g(B / (Z * A)) is square in F. + +Sign of y: Inputs u and -u give the same x-coordinate. +Thus, we set sgn0(y) == sgn0(u). + +Exceptions: The exceptional cases are values of u such that +Z^2 * u^4 + Z * u^2 == 0. This includes u == 0, and may include +other values depending on Z. Implementations must detect +this case and set x1 = B / (Z * A), which guarantees that g(x1) +is square by the condition on Z given above. + +Operations: + +~~~ +1. tv1 = inv0(Z^2 * u^4 + Z * u^2) +2. x1 = (-B / A) * (1 + tv1) +3. If tv1 == 0, set x1 = B / (Z * A) +4. gx1 = x1^3 + A * x1 + B +5. x2 = Z * u^2 * x1 +6. gx2 = x2^3 + A * x2 + B +7. If is_square(gx1), set x = x1 and y = sqrt(gx1) +8. Else set x = x2 and y = sqrt(gx2) +9. If sgn0(u) != sgn0(y), set y = -y +10. return (x, y) +~~~ + +## Simplified SWU for AB == 0 + +Wahby and Boneh show how to adapt the simplified SWU mapping to +Weierstrass curves having A == 0 or B == 0, which the mapping of +simple SWU does not support. + +This method requires finding another elliptic curve E' given by the equation + +~~~ + y'^2 = g'(x') = x'^3 + A' * x' + B' +~~~ + +that is isogenous to E and has A' != 0 and B' != 0. +This isogeny defines a map iso\_map(x', y') given by a pair of rational functions. +iso\_map takes as input a point on E' and produces as output a point on E. + +Once E' and iso\_map are identified, this mapping works as follows: on input +u, first apply the simplified SWU mapping to get a point on E', then apply +the isogeny map to that point to get a point on E. + +Note that iso\_map is a group homomorphism, meaning that point addition +commutes with iso\_map. +Thus, when using this mapping in the hash\_to\_curve construction of {{roadmap}}, +one can effect a small optimization by first mapping u0 and u1 to E', adding +the resulting points on E', and then applying iso\_map to the sum. +This gives the same result while requiring only one evaluation of iso\_map. + +Preconditions: An elliptic curve E' with A' != 0 and B' != 0 that is +isogenous to the target curve E with isogeny map iso\_map from +E' to E. + +So the full mapping algorithm looks as: + +- map\_to\_curve\_simple\_swu is the simple SWU mapping to E' +- iso\_map is the isogeny map from E' to E + +Sign of y: for this map, the sign is determined by map\_to\_curve\_simple\_swu. +No further sign adjustments are necessary. + +Exceptions: map\_to\_curve\_simple\_swu handles its exceptional cases. +Exceptional cases of iso\_map are inputs that cause the denominator of +either rational function to evaluate to zero; such cases MUST return the +identity point on E. + +## Full algorithm restated + +~~~ +1. (x', y') = map_to_curve_simple_swu(u) # (x', y') is on E' +2. (x, y) = iso_map(x', y') # (x, y) is on E +3. (x, y) = clear_cofactor((x, y)) # clears cofactor for point (x, y) on E +4. return (x, y) +~~~ + + +### Fp-to-G1 mapping + + +- Z: 11 +- E': y'^2 = x'^3 + A' * x' + B', where + - A' = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d + - B' = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0 +- h\_eff: 0xd201000000010001 + +The 11-isogeny map from (x', y') on E' to (x, y) on E is given by the following rational functions: + +- x = x\_num / x\_den, where + - x\_num = k\_(1,11) * x'^11 + k\_(1,10) * x'^10 + k\_(1,9) * x'^9 + ... + k\_(1,0) + - x\_den = x'^10 + k\_(2,9) * x'^9 + k\_(2,8) * x'^8 + ... + k\_(2,0) + +- y = y' * y\_num / y\_den, where + - y\_num = k\_(3,15) * x'^15 + k\_(3,14) * x'^14 + k\_(3,13) * x'^13 + ... + k\_(3,0) + - y\_den = x'^15 + k\_(4,14) * x'^14 + k\_(4,13) * x'^13 + ... + k\_(4,0) + +The constants used to compute x\_num are as follows: + +- k\_(1,0) = 0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7 +- k\_(1,1) = 0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb +- k\_(1,2) = 0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0 +- k\_(1,3) = 0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861 +- k\_(1,4) = 0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9 +- k\_(1,5) = 0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983 +- k\_(1,6) = 0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84 +- k\_(1,7) = 0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e +- k\_(1,8) = 0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317 +- k\_(1,9) = 0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e +- k\_(1,10) = 0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b +- k\_(1,11) = 0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229 + +The constants used to compute x\_den are as follows: + +- k\_(2,0) = 0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c +- k\_(2,1) = 0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff +- k\_(2,2) = 0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19 +- k\_(2,3) = 0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8 +- k\_(2,4) = 0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e +- k\_(2,5) = 0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5 +- k\_(2,6) = 0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a +- k\_(2,7) = 0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e +- k\_(2,8) = 0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641 +- k\_(2,9) = 0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a + +The constants used to compute y\_num are as follows: + +- k\_(3,0) = 0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33 +- k\_(3,1) = 0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696 +- k\_(3,2) = 0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6 +- k\_(3,3) = 0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb +- k\_(3,4) = 0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb +- k\_(3,5) = 0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0 +- k\_(3,6) = 0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2 +- k\_(3,7) = 0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29 +- k\_(3,8) = 0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587 +- k\_(3,9) = 0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30 +- k\_(3,10) = 0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132 +- k\_(3,11) = 0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e +- k\_(3,12) = 0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8 +- k\_(3,13) = 0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133 +- k\_(3,14) = 0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b +- k\_(3,15) = 0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604 + +The constants used to compute y\_den are as follows: + +- k\_(4,0) = 0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1 +- k\_(4,1) = 0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d +- k\_(4,2) = 0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2 +- k\_(4,3) = 0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416 +- k\_(4,4) = 0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d +- k\_(4,5) = 0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac +- k\_(4,6) = 0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c +- k\_(4,7) = 0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9 +- k\_(4,8) = 0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a +- k\_(4,9) = 0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55 +- k\_(4,10) = 0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8 +- k\_(4,11) = 0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092 +- k\_(4,12) = 0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc +- k\_(4,13) = 0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7 +- k\_(4,14) = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f + +### Fp2-to-G2 mapping + +Symbol `I` means a non-residue used to make an extension field Fp2 + +- Z: -(2 + I) +- E': y'^2 = x'^3 + A' * x' + B', where + - A' = 240 * I + - B' = 1012 * (1 + I) +- h\_eff: 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551 + +The 3-isogeny map from (x', y') on E' to (x, y) on E is given by the following rational functions: + +- x = x\_num / x\_den, where + - x\_num = k\_(1,3) * x'^3 + k\_(1,2) * x'^2 + k\_(1,1) * x' + k\_(1,0) + - x\_den = x'^2 + k\_(2,1) * x' + k\_(2,0) + +- y = y' * y\_num / y\_den, where + - y\_num = k\_(3,3) * x'^3 + k\_(3,2) * x'^2 + k\_(3,1) * x' + k\_(3,0) + - y\_den = x'^3 + k\_(4,2) * x'^2 + k\_(4,1) * x' + k\_(4,0) + +The constants used to compute x\_num are as follows: + +- k\_(1,0) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 + 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 * I +- k\_(1,1) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a * I +- k\_(1,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d * I +- k\_(1,3) = 0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1 + +The constants used to compute x\_den are as follows: + +- k\_(2,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63 * I +- k\_(2,1) = 0xc + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f * I + +The constants used to compute y\_num are as follows: + +- k\_(3,0) = 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 + 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 * I +- k\_(3,1) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be * I +- k\_(3,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f * I +- k\_(3,3) = 0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10 + +The constants used to compute y\_den are as follows: + +- k\_(4,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb * I +- k\_(4,1) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3 * I +- k\_(4,2) = 0x12 + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99 * I diff --git a/core/cap-tbd.md b/core/cap-tbd.md new file mode 100644 index 000000000..eb52002d0 --- /dev/null +++ b/core/cap-tbd.md @@ -0,0 +1,209 @@ +## Preamble + +``` +CAP: To Be Assigned +Title: Host Functions for BLS12-381 curve operations +Working Group: + Owner: + Authors: + Consulted: +Status: Draft +Created: 2024-01-05 +Discussion: https://github.com/stellar/rs-soroban-env/issues/779 +Protocol version: TBD +``` + +## Simple Summary +Add support for the BLS12-381 elliptical curve to enable zero knowledge proof systems. + +## Working Group + +This section describes the composition of the working group. + +## Motivation +BLS12-381 host functions allow for cryptographic operations in the Soroban execution environment that are otherwise prohibitively expensive. It enables a variety of applications including confidentiality preserving systems, BLS signature schemes, and multiple types of scaling solutions. Pairing-friendly elliptic curves are needed for such systems and BLS12-381 is the state of the art in secure elliptical curves. + + +## Abstract +Add host functions that enable arithmetic, pairing, and mapping operations for points on the BLS12-381 curve. + +## Specification + +### XDR changes + +TBD + +### Semantics +Eleven host functions are added to enable the BLS12-381 curve, which is fully defined in the [supporting docs](https://github.com/namankumar/stellar-protocol/blob/master/contents/cap-tbd/definitions_and_implementation_notes.md). G1 and G2 are two sets of points on the curve. The mathematical relationship between G1 and G2 enables advanced cryptographic systems. + +#### Encoding Rules + +Inputs to the specificed functions need to be encoded as specified. + +#### Encoding Rules: Field elements +Base field element (Fp) is encoded as 64 bytes by performing BigEndian encoding of the corresponding (unsigned) integer (top 16 bytes are always zeroes). 64 bytes are chosen to have 32 byte aligned ABI (representable as e.g. bytes32[2] or uint256[2]). Corresponding integer must be less than field modulus. +For elements of the quadratic extension field (Fp2) encoding is byte concatenation of individual encoding of the coefficients totaling in 128 bytes for a total encoding. + + +#### Encoding Rules: Points in G1 and G2 +Points in either G1 (in base field) or in G2 (in extension field) are encoded as byte concatenation of encodings of the x and y affine coordinates. Total encoding length for G1 point is thus 128 bytes and for G2 point is 256 bytes. + +#### Encoding Rules: Scalars for Multiplication Pperations +Scalar for multiplication operation is encoded as 32 bytes by performing BigEndian encoding of the corresponding (unsigned) integer. Corresponding integer is not required to be less than or equal than main subgroup size. + + +### Data Types +Following types are used throughout this proposal. + +``` + const BLST_G1_POINT: usize = 96; (rename after adding decoding functions) + const BLST_G2_POINT: usize = 192; + const BLST_SCALAR_SIZE: usize = 255; +``` +### Curve Operations + +#### Addition in G1 + +```rust +fn bls12_g1add( e: &Host, p0: BLST_G1_POINT, p1: BLST_G1_POINT) -> Result ; +``` +Perform addition of two points in G1. +Inputs should be 96 bytes each. +An error will be thrown if neither input is in G1, input has invalid length, or encoding rules are violated. + +#### Multiplication in G1 + +```rust +fn bls12_g1mul( e: &Host, scalar: u8, p0: BLST_G1_POINT) -> Result ; +``` +Perform multiplication between a point in G1 and a scalar. +Input should be 96 bytes and 8 bytes. +An error will be thrown if the input p0 is not in G1, input p1 has invalid length, or encoding rules are violated. + +#### Multiexponentiation in G1 + +```rust +fn bls12_g1multiexp( e: &Host, scalars: &[u8], p_n: BLST_G1_POINT) -> Result ; +``` +Perform multipliexponentiation on a point in G1 and a scalar. +Input should be 96 bytes and 8 bytes. +An error will be thrown if the input p_n is not in G1, input p1 has invalid length, or encoding rules are violated. + +#### Addition in G2 + +```rust +fn bls12_g2add( e: &Host, p0: BLST_G2_POINT, p1: BLST_G2_POINT) -> Result ; +``` +Perform addition of two points in G2. +Inputs should be 192 bytes each. +An error will be thrown if neither input is in G2, input has invalid length, or encoding rules are violated. + +#### Multiplication in G2 + +```rust +fn bls12_g2mul( e: &Host, scalar: u8, p0: BLST_G2_POINT) -> Result ; +``` +Perform multiplication between a point in G2 and a scalar. +Input should be 192 bytes and 8 bytes. +An error will be thrown if the input p0 is not in G2, input p2 has invalid length, or encoding rules are violated. + +#### Multiexponentiation in G2 + +```rust +fn bls12_g2multiexp( e: &Host, scalars: &[u8], p_n: BLST_G2_POINT) -> Result ; +``` +Perform multipliexponentiation on a point in G2 and a scalar. +Input should be 192 bytes and 8 bytes. +An error will be thrown if the input p_n is not in G2, input p_n has invalid length, or encoding rules are violated. + +#### Pairing + +```rust +fn bls12_pairing( e: &Host, p_g1: &[BLST_G1_POINT], p_g2: &[BLST_G2_POINT]) -> Result ; +``` + +Perform pairing between points in G1 and G2. +Arguments: +p_g1: point in G1(96 bytes) +p_g1: point in G1(192 bytes) +Returns padded 0x01 if pairing is successful else 0x00. +Error will be thrown if p0_g1 and p1_g1 are not on G1 and G2 respectively, if the points are in the incorrect subgroups, have invalid length, inputs are empty, encoding rules are violated. + +#### Map Base Field Element to G1 + +```rust +fn bls12_map_fp_to_g1( e: &Host, fp: &[u64]) -> Result ; +``` +Map an element of the base field (64 bytes) to a point in G1 (96 bytes). +An error will be thrown if the input p_n is not in G2, input p_n has invalid length, or encoding rules are violated. + +#### Map Extension Field Element to G2 + +```rust +fn bls12_map_fp2_to_g2( e: &Host, fp2: &[u64]) -> Result ; +``` +Map an element of the extension field (64 bytes) to a point in G2 (96 bytes). +An error will be thrown if the input fp2 is not in G2, input fp2 has invalid length, or encoding rules are violated. + +#### Map Arbitrary String to G1 + +```rust +fn bls12_map_hash_to_g1( e: &Host, str: &[u64]) -> Result ; +``` +Map an arbitrary array of bytes (64 bytes) to a point in G1 (96 bytes). +An error will be thrown if the input str is not in G1, input str has invalid length, or encoding rules are violated. + + +#### Map Arbitrary String to G2 + +```rust +fn bls12_map_hash_to_g2( e: &Host, str: &[u64]) -> Result ; +``` +Map an arbitrary byte array (64 bytes) to a point in G2 (192 bytes). +An error will be thrown if the input str is not in G2, input str has invalid length, or encoding rules are violated. + + + +## Design Rationale +The rationale fleshes out the specification by describing what motivated the design and why +particular design decisions were made. It should describe alternate designs that were considered +and related work, e.g. how the feature is supported in other protocols. The rationale may also +provide evidence of consensus within the community, and should discuss important objections or +concerns raised during discussion. + +## Protocol Upgrade Transition +Typically CAPs have a direct impact on core that should be well understood, +and indirect impact on other systems in the ecosystem (Horizon, SDKs, +application, etc). + +The following sections look at common challenges associated with those +protocol transitions. + +### Backwards Incompatibilities +All CAPs that introduce backwards incompatibilities must include a section describing these +incompatibilities and their severity. + +The CAP must propose how to deal with these incompatibilities, potentially pointing to other standard documents that complements the CAP (for example SEPs). + +CAP submissions with an insufficient discussion of backwards compatibility +may be rejected outright. + +### Resource Utilization +Reasonable effort should be made to understand the impact of the CAP on +resource utilization like CPU, memory, network bandwidth and disk/database. + +## Security Concerns +All CAPs should carefully consider areas where security may be a concern, and document them +accordingly. If a change does not have security implications, briefly explain why. + +## Test Cases +Test cases for an implementation are mandatory for CAPs that are affecting consensus changes. Other +CAPs can choose to include links to test cases if applicable. + +## Implementation +The implementation(s) must be completed before any CAP is given "Final" status, but it need not be +completed before the CAP is accepted. While there is merit to the approach of reaching consensus on +the specification and rationale before writing code, the principle of "rough consensus and running +code" is still useful when it comes to resolving many discussions of API details. + +[stellar-core repository]: https://github.com/stellar/stellar-core