Skip to content

Commit

Permalink
Secp256k1Arithmetic: Renames AffinePoint to Point
Browse files Browse the repository at this point in the history
  • Loading branch information
pmerkleplant committed Nov 29, 2023
1 parent 0e97145 commit 29c2e19
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 98 deletions.
4 changes: 2 additions & 2 deletions examples/curves/Secp256k1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {Script} from "forge-std/Script.sol";
import {console2 as console} from "forge-std/console2.sol";

import {Secp256k1, PrivateKey, PublicKey} from "src/curves/Secp256k1.sol";
import {Secp256k1Arithmetic, AffinePoint, JacobianPoint} from "src/curves/Secp256k1Arithmetic.sol";
import {Secp256k1Arithmetic, Point, JacobianPoint} from "src/curves/Secp256k1Arithmetic.sol";

contract Secp256k1Example is Script {
using Secp256k1 for PrivateKey;
Expand All @@ -20,7 +20,7 @@ contract Secp256k1Example is Script {

// Arithmetic types.
// into() -> no memory allocation, to() -> new memory allocation
AffinePoint memory point = pubKey.intoAffinePoint();
Point memory point = pubKey.intoPoint();
JacobianPoint memory jacPoint = pubKey.toJacobianPoint();

// Print some stuff.
Expand Down
22 changes: 11 additions & 11 deletions src/curves/Secp256k1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {Vm} from "forge-std/Vm.sol";

import {
Secp256k1Arithmetic,
AffinePoint,
Point,
JacobianPoint
} from "./Secp256k1Arithmetic.sol";

Expand Down Expand Up @@ -77,8 +77,8 @@ struct PublicKey {
library Secp256k1 {
using Secp256k1 for PrivateKey;
using Secp256k1 for PublicKey;
using Secp256k1 for AffinePoint;
using Secp256k1Arithmetic for AffinePoint;
using Secp256k1 for Point;
using Secp256k1Arithmetic for Point;

// ~~~~~~~ Prelude ~~~~~~~
// forgefmt: disable-start
Expand All @@ -103,7 +103,7 @@ library Secp256k1 {

/// @dev The generator G as PublicKey.
function G() internal pure returns (PublicKey memory) {
AffinePoint memory g = Secp256k1Arithmetic.G();
Point memory g = Secp256k1Arithmetic.G();

return PublicKey(g.x, g.y);
}
Expand Down Expand Up @@ -209,7 +209,7 @@ library Secp256k1 {

/// @dev Returns whether public key `pubKey` is a valid secp256k1 public key.
function isValid(PublicKey memory pubKey) internal pure returns (bool) {
return pubKey.intoAffinePoint().isOnCurve();
return pubKey.intoPoint().isOnCurve();
}

/// @dev Returns the y parity of public key `pubKey`.
Expand All @@ -219,24 +219,24 @@ library Secp256k1 {
///
/// See "Appendix F: Signing Transactions" in the Yellow Paper.
function yParity(PublicKey memory pubKey) internal pure returns (uint) {
return pubKey.intoAffinePoint().yParity();
return pubKey.intoPoint().yParity();
}

/// @dev Mutates public key `pubKey` to Affine Point.
function intoAffinePoint(PublicKey memory pubKey)
/// @dev Mutates public key `pubKey` to Affine point.
function intoPoint(PublicKey memory pubKey)
internal
pure
returns (AffinePoint memory)
returns (Point memory)
{
AffinePoint memory point;
Point memory point;
assembly ("memory-safe") {
point := pubKey
}
return point;
}

/// @dev Mutates Affine point `point` to Public Key.
function intoPublicKey(AffinePoint memory point)
function intoPublicKey(Point memory point)
internal
pure
returns (PublicKey memory)
Expand Down
56 changes: 26 additions & 30 deletions src/curves/Secp256k1Arithmetic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
pragma solidity ^0.8.16;

/**
* @notice AffinePoint is a secp256k1 point in Affine coordinates
* @notice Point is a secp256k1 point in Affine coordinates
*
* @dev The point at infinity is represented via:
* x = y = type(uint).max
*/
struct AffinePoint {
struct Point {
uint x;
uint y;
}
Expand Down Expand Up @@ -50,7 +50,7 @@ struct JacobianPoint {
* @author Inspired by Chronicle Protocol's Scribe (https://github.com/chronicleprotocol/scribe)
*/
library Secp256k1Arithmetic {
using Secp256k1Arithmetic for AffinePoint;
using Secp256k1Arithmetic for Point;
using Secp256k1Arithmetic for JacobianPoint;

//--------------------------------------------------------------------------
Expand All @@ -65,9 +65,9 @@ library Secp256k1Arithmetic {
uint internal constant P =
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;

/// @dev The generator G as AffinePoint.
function G() internal pure returns (AffinePoint memory) {
return AffinePoint(
/// @dev The generator G as Point.
function G() internal pure returns (Point memory) {
return Point(
0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
);
Expand All @@ -81,52 +81,48 @@ library Secp256k1Arithmetic {
//--------------------------------------------------------------------------

//--------------------------------------------------------------------------
// Affine Point
// Point

/// @dev Returns the zero point.
///
/// @dev Note that the zero point is invalid and this function only provided
/// for convenience.
function ZeroPoint() internal pure returns (AffinePoint memory) {
return AffinePoint(0, 0);
function ZeroPoint() internal pure returns (Point memory) {
return Point(0, 0);
}

/// @dev Returns whether Affine point `point` is the zero point.
function isZeroPoint(AffinePoint memory point)
internal
pure
returns (bool)
{
/// @dev Returns whether point `point` is the zero point.
function isZeroPoint(Point memory point) internal pure returns (bool) {
return (point.x | point.y) == 0;
}

/// @dev Returns the point at infinity.
///
/// @dev Note that point at infinity is represented via:
/// point.x = point.y = type(uint).max
function PointAtInfinity() internal pure returns (AffinePoint memory) {
return AffinePoint(type(uint).max, type(uint).max);
function PointAtInfinity() internal pure returns (Point memory) {
return Point(type(uint).max, type(uint).max);
}

/// @dev Returns whether Affine point `point` is the point at infinity.
/// @dev Returns whether point `point` is the point at infinity.
///
/// @dev Note that point at infinity is represented via:
/// point.x = point.y = type(uint).max
function isPointAtInfinity(AffinePoint memory point)
function isPointAtInfinity(Point memory point)
internal
pure
returns (bool)
{
return (point.x & point.y) == type(uint).max;
}

/// @dev Returns whether Affine point `point` is a point on the curve.
/// @dev Returns whether point `point` is on the curve.
///
/// @dev Note that secp256k1 curve is specified as y² ≡ x³ + ax + b (mod P)
/// where:
/// a = 0
/// b = 7
function isOnCurve(AffinePoint memory point) internal pure returns (bool) {
function isOnCurve(Point memory point) internal pure returns (bool) {
uint left = mulmod(point.y, point.y, P);
// Note that adding a * x can be waived as ∀x: a * x = 0.
uint right =
Expand All @@ -135,13 +131,13 @@ library Secp256k1Arithmetic {
return left == right;
}

/// @dev Returns the parity of Affine point `point`'s y coordinate.
/// @dev Returns the parity of point `point`'s y coordinate.
///
/// @dev The value 0 represents an even y value and 1 represents an odd y
/// value.
///
/// See "Appendix F: Signing Transactions" in [Yellow Paper].
function yParity(AffinePoint memory point) internal pure returns (uint) {
function yParity(Point memory point) internal pure returns (uint) {
return point.y & 1;
}

Expand All @@ -154,10 +150,10 @@ library Secp256k1Arithmetic {
// (De)Serialization

//----------------------------------
// Affine Point
// Point

/// @dev Returns Affine point `point` as Jacobian point.
function toJacobianPoint(AffinePoint memory point)
/// @dev Returns point `point` as Jacobian point.
function toJacobianPoint(Point memory point)
internal
pure
returns (JacobianPoint memory)
Expand All @@ -169,10 +165,10 @@ library Secp256k1Arithmetic {
// Jacobian Point

/// @dev Mutates Jacobian point `jacPoint` to Affine point.
function intoAffinePoint(JacobianPoint memory jacPoint)
function intoPoint(JacobianPoint memory jacPoint)
internal
pure
returns (AffinePoint memory)
returns (Point memory)
{
// Compute z⁻¹, i.e. the modular inverse of jacPoint.z.
uint zInv = modularInverseOf(jacPoint.z);
Expand All @@ -194,9 +190,9 @@ library Secp256k1Arithmetic {
mstore(add(jacPoint, 0x20), y)
}

// Return as AffinePoint(jacPoint.x, jacPoint.y).
// Return as Point(jacPoint.x, jacPoint.y).
// Note that jacPoint.z is from now on dirty memory!
AffinePoint memory point;
Point memory point;
assembly ("memory-safe") {
point := jacPoint
}
Expand Down
26 changes: 11 additions & 15 deletions test/curves/secp256k1/Secp256k1.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {console2 as console} from "forge-std/console2.sol";
import {Secp256k1, PrivateKey, PublicKey} from "src/curves/Secp256k1.sol";
import {
Secp256k1Arithmetic,
AffinePoint,
Point,
JacobianPoint
} from "src/curves/Secp256k1Arithmetic.sol";

Expand Down Expand Up @@ -157,23 +157,19 @@ contract Secp256k1Test is Test {
assertEq(want, got);
}

// -- intoAffinePoint
// -- intoPoint

// @todo Add no memory expansion tests for `into__()` functions.
// Must directly use library, not wrapper.

function testFuzz_PublicKey_intoAffinePoint(PublicKey memory pubKey)
public
{
AffinePoint memory point = wrapper.intoAffinePoint(pubKey);
function testFuzz_PublicKey_intoPoint(PublicKey memory pubKey) public {
Point memory point = wrapper.intoPoint(pubKey);

assertEq(point.x, pubKey.x);
assertEq(point.y, pubKey.y);
}

function testFuzz_AffinePoint_intoPublicKey(AffinePoint memory point)
public
{
function testFuzz_Point_intoPublicKey(Point memory point) public {
PublicKey memory pubKey = wrapper.intoPublicKey(point);

assertEq(pubKey.x, point.x);
Expand Down Expand Up @@ -352,8 +348,8 @@ contract Secp256k1Test is Test {
contract Secp256k1Wrapper {
using Secp256k1 for PrivateKey;
using Secp256k1 for PublicKey;
using Secp256k1 for AffinePoint;
using Secp256k1Arithmetic for AffinePoint;
using Secp256k1 for Point;
using Secp256k1Arithmetic for Point;

//--------------------------------------------------------------------------
// Constants
Expand Down Expand Up @@ -407,15 +403,15 @@ contract Secp256k1Wrapper {
return pubKey.yParity();
}

function intoAffinePoint(PublicKey memory pubKey)
function intoPoint(PublicKey memory pubKey)
public
pure
returns (AffinePoint memory)
returns (Point memory)
{
return pubKey.intoAffinePoint();
return pubKey.intoPoint();
}

function intoPublicKey(AffinePoint memory point)
function intoPublicKey(Point memory point)
public
pure
returns (PublicKey memory)
Expand Down
Loading

0 comments on commit 29c2e19

Please sign in to comment.