|
|
@@ -22,1328 +22,1197 @@ unit ClpSecP384R1Custom;
|
|
|
interface
|
|
|
|
|
|
uses
|
|
|
+ SysUtils,
|
|
|
+ ClpBigInteger,
|
|
|
+ ClpBigIntegers,
|
|
|
+ ClpNat384,
|
|
|
+ ClpNat,
|
|
|
ClpMod,
|
|
|
+ ClpPack,
|
|
|
ClpEncoders,
|
|
|
- ClpNat,
|
|
|
+ ClpSecureRandom,
|
|
|
+ ClpISecureRandom,
|
|
|
+ ClpArrayUtilities,
|
|
|
ClpBitOperations,
|
|
|
- ClpNat384,
|
|
|
ClpECCurve,
|
|
|
- ClpBigInteger,
|
|
|
- ClpArrayUtilities,
|
|
|
- ClpCryptoLibTypes,
|
|
|
ClpECCurveConstants,
|
|
|
+ ClpECFieldElement,
|
|
|
+ ClpECPoint,
|
|
|
+ ClpECLookupTables,
|
|
|
+ ClpFiniteFields,
|
|
|
ClpIECCore,
|
|
|
ClpIECFieldElement,
|
|
|
- ClpISecP384R1Custom;
|
|
|
+ ClpISecP384R1Custom,
|
|
|
+ ClpCryptoLibTypes;
|
|
|
|
|
|
resourcestring
|
|
|
- SInvalidValueForSecP384R1FieldElement =
|
|
|
- 'Value Invalid for SecP384R1FieldElement "%s"';
|
|
|
- SOneOfECFieldElementIsNil = 'Exactly One of the Field Elements is Nil';
|
|
|
+ SInvalidSecP384R1FieldElement = 'value invalid for SecP384R1FieldElement';
|
|
|
|
|
|
type
|
|
|
- // 2^384 - 2^128 - 2^96 + 2^32 - 1
|
|
|
TSecP384R1Field = class sealed(TObject)
|
|
|
-
|
|
|
strict private
|
|
|
const
|
|
|
P11 = UInt32($FFFFFFFF);
|
|
|
PExt23 = UInt32($FFFFFFFF);
|
|
|
-
|
|
|
- class var
|
|
|
-
|
|
|
- FP, FPExt, FPExtInv: TCryptoLibUInt32Array;
|
|
|
-
|
|
|
- class function GetP: TCryptoLibUInt32Array; static; inline;
|
|
|
-
|
|
|
- class procedure AddPInvTo(const z: TCryptoLibUInt32Array); static;
|
|
|
- class procedure SubPInvFrom(const z: TCryptoLibUInt32Array); static;
|
|
|
-
|
|
|
- class procedure Boot(); static;
|
|
|
- class constructor SecP384R1Field();
|
|
|
-
|
|
|
+ class var
|
|
|
+ FP, FPExt, FPExtInv: TCryptoLibUInt32Array;
|
|
|
+ class procedure Boot; static;
|
|
|
+ class procedure AddPInvTo(const AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure SubPInvFrom(const AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class constructor Create;
|
|
|
public
|
|
|
- class procedure Add(const x, y, z: TCryptoLibUInt32Array); static; inline;
|
|
|
- class procedure AddExt(const xx, yy, zz: TCryptoLibUInt32Array);
|
|
|
- static; inline;
|
|
|
- class procedure AddOne(const x, z: TCryptoLibUInt32Array); static; inline;
|
|
|
- class function FromBigInteger(const x: TBigInteger): TCryptoLibUInt32Array;
|
|
|
- static; inline;
|
|
|
- class procedure Half(const x, z: TCryptoLibUInt32Array); static; inline;
|
|
|
- class procedure Multiply(const x, y, z: TCryptoLibUInt32Array);
|
|
|
- static; inline;
|
|
|
- class procedure Negate(const x, z: TCryptoLibUInt32Array); static; inline;
|
|
|
- class procedure Reduce(const xx, z: TCryptoLibUInt32Array); static;
|
|
|
- class procedure Reduce32(x: UInt32; const z: TCryptoLibUInt32Array); static;
|
|
|
- class procedure Square(const x, z: TCryptoLibUInt32Array); static; inline;
|
|
|
- class procedure SquareN(const x: TCryptoLibUInt32Array; n: Int32;
|
|
|
- const z: TCryptoLibUInt32Array); static; inline;
|
|
|
- class procedure Subtract(const x, y, z: TCryptoLibUInt32Array);
|
|
|
- static; inline;
|
|
|
- class procedure SubtractExt(const xx, yy, zz: TCryptoLibUInt32Array);
|
|
|
- static; inline;
|
|
|
- class procedure Twice(const x, z: TCryptoLibUInt32Array); static; inline;
|
|
|
-
|
|
|
- class property P: TCryptoLibUInt32Array read GetP;
|
|
|
+ class procedure Add(const AX, AY, AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure AddExt(const AXX, AYY, AZZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure AddOne(const AX, AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class function FromBigInteger(const AX: TBigInteger): TCryptoLibUInt32Array; static;
|
|
|
+ class procedure Half(const AX, AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure Inv(const AX, AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class function IsZero(const AX: TCryptoLibUInt32Array): Int32; static;
|
|
|
+ class procedure Multiply(const AX, AY, AZ: TCryptoLibUInt32Array); overload; static;
|
|
|
+ class procedure Multiply(const AX, AY, AZ, ATT: TCryptoLibUInt32Array); overload; static;
|
|
|
+ class procedure Negate(const AX, AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure Random(const AR: ISecureRandom; const AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure RandomMult(const AR: ISecureRandom; const AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure Reduce(const AXX, AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure Reduce32(AX: UInt32; const AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure Square(const AX, AZ: TCryptoLibUInt32Array); overload; static;
|
|
|
+ class procedure Square(const AX, AZ, ATT: TCryptoLibUInt32Array); overload; static;
|
|
|
+ class procedure SquareN(const AX: TCryptoLibUInt32Array; AN: Int32;
|
|
|
+ const AZ: TCryptoLibUInt32Array); overload; static;
|
|
|
+ class procedure SquareN(const AX: TCryptoLibUInt32Array; AN: Int32;
|
|
|
+ const AZ, ATT: TCryptoLibUInt32Array); overload; static;
|
|
|
+ class procedure Subtract(const AX, AY, AZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure SubtractExt(const AXX, AYY, AZZ: TCryptoLibUInt32Array); static;
|
|
|
+ class procedure Twice(const AX, AZ: TCryptoLibUInt32Array); static;
|
|
|
+
|
|
|
+ class property P: TCryptoLibUInt32Array read FP;
|
|
|
end;
|
|
|
|
|
|
type
|
|
|
- TSecP384R1FieldElement = class(TAbstractFpFieldElement,
|
|
|
- ISecP384R1FieldElement)
|
|
|
-
|
|
|
+ TSecP384R1FieldElement = class sealed(TAbstractFpFieldElement,
|
|
|
+ IAbstractFpFieldElement, IECFieldElement, ISecP384R1FieldElement)
|
|
|
strict private
|
|
|
-
|
|
|
- function Equals(const AOther: ISecP384R1FieldElement): Boolean;
|
|
|
- reintroduce; overload;
|
|
|
-
|
|
|
- class function GetQ: TBigInteger; static; inline;
|
|
|
-
|
|
|
+ class var
|
|
|
+ FQ: TBigInteger;
|
|
|
+ class procedure Boot; static;
|
|
|
+ class constructor Create;
|
|
|
strict protected
|
|
|
- var
|
|
|
- Fx: TCryptoLibUInt32Array;
|
|
|
-
|
|
|
- function GetFieldName: string; override;
|
|
|
- function GetFieldSize: Int32; override;
|
|
|
- function GetIsOne: Boolean; override;
|
|
|
- function GetIsZero: Boolean; override;
|
|
|
-
|
|
|
+ FX: TCryptoLibUInt32Array;
|
|
|
function GetX: TCryptoLibUInt32Array; inline;
|
|
|
- property x: TCryptoLibUInt32Array read GetX;
|
|
|
-
|
|
|
public
|
|
|
+ class function GetQ: TBigInteger; static;
|
|
|
+ class property Q: TBigInteger read GetQ;
|
|
|
+ constructor Create(const AX: TBigInteger); overload;
|
|
|
constructor Create(); overload;
|
|
|
- constructor Create(const x: TBigInteger); overload;
|
|
|
- constructor Create(const x: TCryptoLibUInt32Array); overload;
|
|
|
+ constructor Create(const AX: TCryptoLibUInt32Array); overload;
|
|
|
|
|
|
+ function GetFieldName: String; override;
|
|
|
+ function GetFieldSize: Int32; override;
|
|
|
+ function GetIsOne: Boolean; override;
|
|
|
+ function GetIsZero: Boolean; override;
|
|
|
+ function ToBigInteger: TBigInteger; override;
|
|
|
function TestBitZero: Boolean; override;
|
|
|
- function ToBigInteger(): TBigInteger; override;
|
|
|
|
|
|
- function Add(const b: IECFieldElement): IECFieldElement; override;
|
|
|
- function AddOne(): IECFieldElement; override;
|
|
|
- function Subtract(const b: IECFieldElement): IECFieldElement; override;
|
|
|
+ function Add(const AB: IECFieldElement): IECFieldElement; override;
|
|
|
+ function AddOne: IECFieldElement; override;
|
|
|
+ function Subtract(const AB: IECFieldElement): IECFieldElement; override;
|
|
|
+ function Multiply(const AB: IECFieldElement): IECFieldElement; override;
|
|
|
+ function Divide(const AB: IECFieldElement): IECFieldElement; override;
|
|
|
+ function Negate: IECFieldElement; override;
|
|
|
+ function Square: IECFieldElement; override;
|
|
|
+ function Invert: IECFieldElement; override;
|
|
|
+ function Sqrt: IECFieldElement; override;
|
|
|
|
|
|
- function Multiply(const b: IECFieldElement): IECFieldElement; override;
|
|
|
- function Divide(const b: IECFieldElement): IECFieldElement; override;
|
|
|
- function Negate(): IECFieldElement; override;
|
|
|
- function Square(): IECFieldElement; override;
|
|
|
+ function Equals(const AOther: IECFieldElement): Boolean; override;
|
|
|
+ function GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt; {$ENDIF DELPHI} override;
|
|
|
|
|
|
- function Invert(): IECFieldElement; override;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// return a sqrt root - the routine verifies that the calculation
|
|
|
- /// returns the right value - if <br />none exists it returns null.
|
|
|
- /// </summary>
|
|
|
- function Sqrt(): IECFieldElement; override;
|
|
|
-
|
|
|
- function Equals(const AOther: IECFieldElement): Boolean; overload; override;
|
|
|
-
|
|
|
- function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
|
|
|
-{$ENDIF DELPHI}override;
|
|
|
-
|
|
|
- property IsZero: Boolean read GetIsZero;
|
|
|
- property IsOne: Boolean read GetIsOne;
|
|
|
- property FieldName: string read GetFieldName;
|
|
|
- property FieldSize: Int32 read GetFieldSize;
|
|
|
-
|
|
|
- class property Q: TBigInteger read GetQ;
|
|
|
+ property X: TCryptoLibUInt32Array read GetX;
|
|
|
end;
|
|
|
|
|
|
type
|
|
|
- TSecP384R1Point = class sealed(TAbstractFpPoint, ISecP384R1Point)
|
|
|
-
|
|
|
+ TSecP384R1Point = class sealed(TAbstractFpPoint, IAbstractFpPoint, IECPoint,
|
|
|
+ ISecP384R1Point)
|
|
|
strict protected
|
|
|
- function Detach(): IECPoint; override;
|
|
|
-
|
|
|
+ function Detach: IECPoint; override;
|
|
|
public
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Create a point which encodes without point compression.
|
|
|
- /// </summary>
|
|
|
- /// <param name="curve">
|
|
|
- /// the curve to use
|
|
|
- /// </param>
|
|
|
- /// <param name="x">
|
|
|
- /// affine x co-ordinate
|
|
|
- /// </param>
|
|
|
- /// <param name="y">
|
|
|
- /// affine y co-ordinate
|
|
|
- /// </param>
|
|
|
- constructor Create(const curve: IECCurve; const x, y: IECFieldElement);
|
|
|
- overload; deprecated 'Use ECCurve.createPoint to construct points';
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Create a point that encodes with or without point compresion.
|
|
|
- /// </summary>
|
|
|
- /// <param name="curve">
|
|
|
- /// the curve to use
|
|
|
- /// </param>
|
|
|
- /// <param name="x">
|
|
|
- /// affine x co-ordinate
|
|
|
- /// </param>
|
|
|
- /// <param name="y">
|
|
|
- /// affine y co-ordinate
|
|
|
- /// </param>
|
|
|
- /// <param name="withCompression">
|
|
|
- /// if true encode with point compression
|
|
|
- /// </param>
|
|
|
- constructor Create(const curve: IECCurve; const x, y: IECFieldElement;
|
|
|
- withCompression: Boolean); overload;
|
|
|
- deprecated
|
|
|
- 'Per-point compression property will be removed, see GetEncoded(boolean)';
|
|
|
-
|
|
|
- constructor Create(const curve: IECCurve; const x, y: IECFieldElement;
|
|
|
- const zs: TCryptoLibGenericArray<IECFieldElement>;
|
|
|
- withCompression: Boolean); overload;
|
|
|
-
|
|
|
- function Add(const b: IECPoint): IECPoint; override;
|
|
|
- function Negate(): IECPoint; override;
|
|
|
-
|
|
|
- function Twice(): IECPoint; override;
|
|
|
- function TwicePlus(const b: IECPoint): IECPoint; override;
|
|
|
-
|
|
|
- function ThreeTimes(): IECPoint; override;
|
|
|
-
|
|
|
+ constructor Create(const ACurve: IECCurve; const AX, AY: IECFieldElement); overload;
|
|
|
+ constructor Create(const ACurve: IECCurve; const AX, AY: IECFieldElement;
|
|
|
+ const AZs: TCryptoLibGenericArray<IECFieldElement>); overload;
|
|
|
+
|
|
|
+ function Add(const AB: IECPoint): IECPoint; override;
|
|
|
+ function Twice: IECPoint; override;
|
|
|
+ function TwicePlus(const AB: IECPoint): IECPoint; override;
|
|
|
+ function ThreeTimes: IECPoint; override;
|
|
|
+ function Negate: IECPoint; override;
|
|
|
end;
|
|
|
|
|
|
type
|
|
|
- TSecP384R1Curve = class sealed(TAbstractFpCurve, ISecP384R1Curve)
|
|
|
-
|
|
|
+ TSecP384R1Curve = class sealed(TAbstractFpCurve, IAbstractFpCurve, IECCurve,
|
|
|
+ ISecP384R1Curve)
|
|
|
+ strict private
|
|
|
+ const
|
|
|
+ SECP384R1_DEFAULT_COORDS = TECCurveConstants.COORD_JACOBIAN;
|
|
|
+ SECP384R1_FE_INTS = 12;
|
|
|
strict private
|
|
|
-
|
|
|
type
|
|
|
- TSecP384R1LookupTable = class sealed(TAbstractECLookupTable,
|
|
|
+ TSecP384R1LookupTable = class sealed(TAbstractECLookupTable, IECLookupTable,
|
|
|
ISecP384R1LookupTable)
|
|
|
-
|
|
|
strict private
|
|
|
- var
|
|
|
- Fm_outer: ISecP384R1Curve;
|
|
|
- Fm_table: TCryptoLibUInt32Array;
|
|
|
- Fm_size: Int32;
|
|
|
-
|
|
|
- function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
|
|
|
-
|
|
|
- strict protected
|
|
|
-
|
|
|
- function GetSize: Int32; override;
|
|
|
-
|
|
|
+ FOuter: ISecP384R1Curve;
|
|
|
+ FTable: TCryptoLibUInt32Array;
|
|
|
+ FSize: Int32;
|
|
|
+ function CreatePoint(const AX, AY: TCryptoLibUInt32Array): IECPoint;
|
|
|
public
|
|
|
-
|
|
|
- constructor Create(const outer: ISecP384R1Curve;
|
|
|
- const table: TCryptoLibUInt32Array; size: Int32);
|
|
|
-
|
|
|
- function Lookup(index: Int32): IECPoint; override;
|
|
|
- function LookupVar(index: Int32): IECPoint; override;
|
|
|
-
|
|
|
+ constructor Create(const AOuter: ISecP384R1Curve;
|
|
|
+ const ATable: TCryptoLibUInt32Array; ASize: Int32);
|
|
|
+ function GetSize: Int32; override;
|
|
|
+ function Lookup(AIndex: Int32): IECPoint; override;
|
|
|
+ function LookupVar(AIndex: Int32): IECPoint; override;
|
|
|
end;
|
|
|
-
|
|
|
- const
|
|
|
- SECP384R1_DEFAULT_COORDS = Int32(TECCurveConstants.COORD_JACOBIAN);
|
|
|
- SECP384R1_FE_INTS = Int32(12);
|
|
|
-
|
|
|
+ class var
|
|
|
+ FQ: TBigInteger;
|
|
|
+ FSecP384R1AffineZs: TCryptoLibGenericArray<IECFieldElement>;
|
|
|
+ class procedure Boot; static;
|
|
|
+ class constructor Create;
|
|
|
var
|
|
|
- Fq: TBigInteger;
|
|
|
-
|
|
|
+ FInfinity: TSecP384R1Point;
|
|
|
strict protected
|
|
|
- var
|
|
|
- Fm_infinity: ISecP384R1Point;
|
|
|
+ function GetQ: TBigInteger;
|
|
|
+ public
|
|
|
+ constructor Create;
|
|
|
+ destructor Destroy; override;
|
|
|
|
|
|
- function GetQ: TBigInteger; virtual;
|
|
|
+ function CloneCurve: IECCurve; override;
|
|
|
function GetFieldSize: Int32; override;
|
|
|
function GetInfinity: IECPoint; override;
|
|
|
-
|
|
|
- function CloneCurve(): IECCurve; override;
|
|
|
-
|
|
|
- function CreateRawPoint(const x, y: IECFieldElement;
|
|
|
- withCompression: Boolean): IECPoint; overload; override;
|
|
|
-
|
|
|
- function CreateRawPoint(const x, y: IECFieldElement;
|
|
|
- const zs: TCryptoLibGenericArray<IECFieldElement>;
|
|
|
- withCompression: Boolean): IECPoint; overload; override;
|
|
|
-
|
|
|
- public
|
|
|
- constructor Create();
|
|
|
- function FromBigInteger(const x: TBigInteger): IECFieldElement; override;
|
|
|
-
|
|
|
- function SupportsCoordinateSystem(coord: Int32): Boolean; override;
|
|
|
-
|
|
|
- function CreateCacheSafeLookupTable(const points
|
|
|
- : TCryptoLibGenericArray<IECPoint>; off, len: Int32)
|
|
|
- : IECLookupTable; override;
|
|
|
-
|
|
|
- property Q: TBigInteger read GetQ;
|
|
|
- property Infinity: IECPoint read GetInfinity;
|
|
|
- property FieldSize: Int32 read GetFieldSize;
|
|
|
-
|
|
|
+ function FromBigInteger(const AX: TBigInteger): IECFieldElement; override;
|
|
|
+ function CreateRawPoint(const AX, AY: IECFieldElement): IECPoint; override;
|
|
|
+ function CreateRawPoint(const AX, AY: IECFieldElement;
|
|
|
+ const AZs: TCryptoLibGenericArray<IECFieldElement>): IECPoint; override;
|
|
|
+ function CreateCacheSafeLookupTable(const APoints: TCryptoLibGenericArray<IECPoint>;
|
|
|
+ AOff, ALen: Int32): IECLookupTable; override;
|
|
|
+ function RandomFieldElement(const ARandom: ISecureRandom): IECFieldElement; override;
|
|
|
+ function RandomFieldElementMult(const ARandom: ISecureRandom): IECFieldElement; override;
|
|
|
+ function SupportsCoordinateSystem(ACoord: Int32): Boolean; override;
|
|
|
+
|
|
|
+ class property Q: TBigInteger read FQ;
|
|
|
+ class property SecP384R1AffineZs: TCryptoLibGenericArray<IECFieldElement> read FSecP384R1AffineZs;
|
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
|
|
{ TSecP384R1Field }
|
|
|
|
|
|
-class constructor TSecP384R1Field.SecP384R1Field;
|
|
|
+class procedure TSecP384R1Field.Boot;
|
|
|
begin
|
|
|
- TSecP384R1Field.Boot;
|
|
|
+ FP := TCryptoLibUInt32Array.Create($FFFFFFFF, $00000000, $00000000, $FFFFFFFF,
|
|
|
+ $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
|
|
|
+ FPExt := TCryptoLibUInt32Array.Create($00000001, $FFFFFFFE, $00000000, $00000002,
|
|
|
+ $00000000, $FFFFFFFE, $00000000, $00000002, $00000001, $00000000, $00000000, $00000000,
|
|
|
+ $FFFFFFFE, $00000001, $00000000, $FFFFFFFE, $FFFFFFFD, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
|
|
|
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
|
|
|
+ FPExtInv := TCryptoLibUInt32Array.Create($FFFFFFFF, $00000001, $FFFFFFFF, $FFFFFFFD,
|
|
|
+ $FFFFFFFF, $00000001, $FFFFFFFF, $FFFFFFFD, $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
|
|
|
+ $00000001, $FFFFFFFE, $FFFFFFFF, $00000001, $00000002);
|
|
|
end;
|
|
|
|
|
|
-class function TSecP384R1Field.GetP: TCryptoLibUInt32Array;
|
|
|
+class constructor TSecP384R1Field.Create;
|
|
|
begin
|
|
|
- result := FP;
|
|
|
+ Boot;
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.AddPInvTo(const z: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.AddPInvTo(const AZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- c: Int64;
|
|
|
-begin
|
|
|
- c := Int64(z[0]) + 1;
|
|
|
- z[0] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- c := c + (Int64(z[1]) - 1);
|
|
|
- z[1] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- if (c <> 0) then
|
|
|
- begin
|
|
|
- c := c + Int64(z[2]);
|
|
|
- z[2] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- end;
|
|
|
- c := c + (Int64(z[3]) + 1);
|
|
|
- z[3] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- c := c + (Int64(z[4]) + 1);
|
|
|
- z[4] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- if (c <> 0) then
|
|
|
+ LC: Int64;
|
|
|
+begin
|
|
|
+ LC := Int64(AZ[0]) + 1;
|
|
|
+ AZ[0] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
+ LC := LC + (Int64(AZ[1]) - 1);
|
|
|
+ AZ[1] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
+ if LC <> 0 then
|
|
|
begin
|
|
|
- TNat.IncAt(12, z, 5);
|
|
|
+ LC := LC + Int64(AZ[2]);
|
|
|
+ AZ[2] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
end;
|
|
|
+ LC := LC + (Int64(AZ[3]) + 1);
|
|
|
+ AZ[3] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
+ LC := LC + (Int64(AZ[4]) + 1);
|
|
|
+ AZ[4] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
+ if LC <> 0 then
|
|
|
+ TNat.IncAt(12, AZ, 5);
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.Boot;
|
|
|
-begin
|
|
|
- FP := TCryptoLibUInt32Array.Create($FFFFFFFF, $00000000, $00000000, $FFFFFFFF,
|
|
|
- $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
|
|
|
- $FFFFFFFF);
|
|
|
- FPExt := TCryptoLibUInt32Array.Create($00000001, $FFFFFFFE, $00000000,
|
|
|
- $00000002, $00000000, $FFFFFFFE, $00000000, $00000002, $00000001, $00000000,
|
|
|
- $00000000, $00000000, $FFFFFFFE, $00000001, $00000000, $FFFFFFFE, $FFFFFFFD,
|
|
|
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
|
|
|
- $FFFFFFFF);
|
|
|
- FPExtInv := TCryptoLibUInt32Array.Create($FFFFFFFF, $00000001, $FFFFFFFF,
|
|
|
- $FFFFFFFD, $FFFFFFFF, $00000001, $FFFFFFFF, $FFFFFFFD, $FFFFFFFE, $FFFFFFFF,
|
|
|
- $FFFFFFFF, $FFFFFFFF, $00000001, $FFFFFFFE, $FFFFFFFF, $00000001,
|
|
|
- $00000002);
|
|
|
-end;
|
|
|
-
|
|
|
-class procedure TSecP384R1Field.SubPInvFrom(const z: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.SubPInvFrom(const AZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- c: Int64;
|
|
|
-begin
|
|
|
- c := Int64(z[0]) - 1;
|
|
|
- z[0] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- c := c + (Int64(z[1]) + 1);
|
|
|
- z[1] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- if (c <> 0) then
|
|
|
- begin
|
|
|
- c := c + Int64(z[2]);
|
|
|
- z[2] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- end;
|
|
|
- c := c + (Int64(z[3]) - 1);
|
|
|
- z[3] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- c := c + (Int64(z[4]) - 1);
|
|
|
- z[4] := UInt32(c);
|
|
|
- c := TBitOperations.Asr64(c, 32);
|
|
|
- if (c <> 0) then
|
|
|
+ LC: Int64;
|
|
|
+begin
|
|
|
+ LC := Int64(AZ[0]) - 1;
|
|
|
+ AZ[0] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
+ LC := LC + (Int64(AZ[1]) + 1);
|
|
|
+ AZ[1] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
+ if LC <> 0 then
|
|
|
begin
|
|
|
- TNat.DecAt(12, z, 5);
|
|
|
+ LC := LC + Int64(AZ[2]);
|
|
|
+ AZ[2] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
end;
|
|
|
+ LC := LC + (Int64(AZ[3]) - 1);
|
|
|
+ AZ[3] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
+ LC := LC + (Int64(AZ[4]) - 1);
|
|
|
+ AZ[4] := UInt32(LC);
|
|
|
+ LC := TBitOperations.Asr64(LC, 32);
|
|
|
+ if LC <> 0 then
|
|
|
+ TNat.DecAt(12, AZ, 5);
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.Add(const x, y, z: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.Add(const AX, AY, AZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- c: UInt32;
|
|
|
+ LC: UInt32;
|
|
|
begin
|
|
|
- c := TNat.Add(12, x, y, z);
|
|
|
- if ((c <> 0) or ((z[11] = P11) and (TNat.Gte(12, z, FP)))) then
|
|
|
- begin
|
|
|
- AddPInvTo(z);
|
|
|
- end;
|
|
|
+ LC := TNat.Add(12, AX, AY, AZ);
|
|
|
+ if (LC <> 0) or ((AZ[11] = P11) and TNat.Gte(12, AZ, FP)) then
|
|
|
+ AddPInvTo(AZ);
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.AddExt(const xx, yy, zz: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.AddExt(const AXX, AYY, AZZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- c: UInt32;
|
|
|
+ LC: UInt32;
|
|
|
begin
|
|
|
- c := TNat.Add(24, xx, yy, zz);
|
|
|
- if ((c <> 0) or ((zz[23] = PExt23) and (TNat.Gte(24, zz, FPExt)))) then
|
|
|
- begin
|
|
|
- if (TNat.AddTo(System.Length(FPExtInv), FPExtInv, zz) <> 0) then
|
|
|
- begin
|
|
|
- TNat.IncAt(24, zz, System.Length(FPExtInv));
|
|
|
- end;
|
|
|
- end;
|
|
|
+ LC := TNat.Add(24, AXX, AYY, AZZ);
|
|
|
+ if (LC <> 0) or ((AZZ[23] = PExt23) and TNat.Gte(24, AZZ, FPExt)) then
|
|
|
+ if TNat.AddTo(System.Length(FPExtInv), FPExtInv, AZZ) <> 0 then
|
|
|
+ TNat.IncAt(24, AZZ, System.Length(FPExtInv));
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.AddOne(const x, z: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.AddOne(const AX, AZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- c: UInt32;
|
|
|
+ LC: UInt32;
|
|
|
begin
|
|
|
- c := TNat.Inc(12, x, z);
|
|
|
- if ((c <> 0) or ((z[11] = P11) and (TNat.Gte(12, z, FP)))) then
|
|
|
- begin
|
|
|
- AddPInvTo(z);
|
|
|
- end;
|
|
|
+ LC := TNat.Inc(12, AX, AZ);
|
|
|
+ if (LC <> 0) or ((AZ[11] = P11) and TNat.Gte(12, AZ, FP)) then
|
|
|
+ AddPInvTo(AZ);
|
|
|
end;
|
|
|
|
|
|
-class function TSecP384R1Field.FromBigInteger(const x: TBigInteger)
|
|
|
- : TCryptoLibUInt32Array;
|
|
|
+class function TSecP384R1Field.FromBigInteger(const AX: TBigInteger): TCryptoLibUInt32Array;
|
|
|
var
|
|
|
- z: TCryptoLibUInt32Array;
|
|
|
+ LZ: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- z := TNat.FromBigInteger(384, x);
|
|
|
- if ((z[11] = P11) and (TNat.Gte(12, z, FP))) then
|
|
|
- begin
|
|
|
- TNat.SubFrom(12, FP, z);
|
|
|
- end;
|
|
|
- result := z;
|
|
|
+ LZ := TNat.FromBigInteger(384, AX);
|
|
|
+ if (LZ[11] = P11) and TNat.Gte(12, LZ, FP) then
|
|
|
+ TNat.SubFrom(12, FP, LZ);
|
|
|
+ Result := LZ;
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.Half(const x, z: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.Half(const AX, AZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- c: UInt32;
|
|
|
+ LC: UInt32;
|
|
|
begin
|
|
|
- if ((x[0] and 1) = 0) then
|
|
|
- begin
|
|
|
- TNat.ShiftDownBit(12, x, 0, z);
|
|
|
- end
|
|
|
+ if (AX[0] and 1) = 0 then
|
|
|
+ TNat.ShiftDownBit(12, AX, 0, AZ)
|
|
|
else
|
|
|
begin
|
|
|
- c := TNat.Add(12, x, FP, z);
|
|
|
- TNat.ShiftDownBit(12, z, c);
|
|
|
+ LC := TNat.Add(12, AX, FP, AZ);
|
|
|
+ TNat.ShiftDownBit(12, AZ, LC);
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.Reduce32(x: UInt32;
|
|
|
- const z: TCryptoLibUInt32Array);
|
|
|
-var
|
|
|
- cc, xx12: Int64;
|
|
|
+class procedure TSecP384R1Field.Inv(const AX, AZ: TCryptoLibUInt32Array);
|
|
|
begin
|
|
|
- cc := 0;
|
|
|
-
|
|
|
- if (x <> 0) then
|
|
|
- begin
|
|
|
- xx12 := x;
|
|
|
-
|
|
|
- cc := cc + (Int64(z[0]) + xx12);
|
|
|
- z[0] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(z[1]) - xx12);
|
|
|
- z[1] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- if (cc <> 0) then
|
|
|
- begin
|
|
|
- cc := cc + Int64(z[2]);
|
|
|
- z[2] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- end;
|
|
|
- cc := cc + (Int64(z[3]) + xx12);
|
|
|
- z[3] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(z[4]) + xx12);
|
|
|
- z[4] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
-
|
|
|
-{$IFDEF DEBUG}
|
|
|
- System.Assert((cc = 0) or (cc = 1));
|
|
|
-{$ENDIF DEBUG}
|
|
|
- end;
|
|
|
-
|
|
|
- if (((cc <> 0) and (TNat.IncAt(12, z, 5) <> 0)) or
|
|
|
- ((z[11] = P11) and (TNat.Gte(12, z, FP)))) then
|
|
|
- begin
|
|
|
- AddPInvTo(z);
|
|
|
- end;
|
|
|
+ TMod.CheckedModOddInverse(FP, AX, AZ);
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.Reduce(const xx, z: TCryptoLibUInt32Array);
|
|
|
-const
|
|
|
- n: Int64 = 1;
|
|
|
+class function TSecP384R1Field.IsZero(const AX: TCryptoLibUInt32Array): Int32;
|
|
|
var
|
|
|
- cc, xx16, xx17, xx18, xx19, xx20, xx21, xx22, xx23, t0, t1, t2, t3, t4, t5,
|
|
|
- t6, t7: Int64;
|
|
|
-
|
|
|
-begin
|
|
|
- xx16 := xx[16];
|
|
|
- xx17 := xx[17];
|
|
|
- xx18 := xx[18];
|
|
|
- xx19 := xx[19];
|
|
|
- xx20 := xx[20];
|
|
|
- xx21 := xx[21];
|
|
|
- xx22 := xx[22];
|
|
|
- xx23 := xx[23];
|
|
|
-
|
|
|
- t0 := Int64(xx[12]) + xx20 - n;
|
|
|
- t1 := Int64(xx[13]) + xx22;
|
|
|
- t2 := Int64(xx[14]) + xx22 + xx23;
|
|
|
- t3 := Int64(xx[15]) + xx23;
|
|
|
- t4 := xx17 + xx21;
|
|
|
- t5 := xx21 - xx23;
|
|
|
- t6 := xx22 - xx23;
|
|
|
- t7 := t0 + t5;
|
|
|
-
|
|
|
- cc := 0;
|
|
|
- cc := cc + (Int64(xx[0]) + t7);
|
|
|
- z[0] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[1]) + xx23 - t0 + t1);
|
|
|
- z[1] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[2]) - xx21 - t1 + t2);
|
|
|
- z[2] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[3]) - t2 + t3 + t7);
|
|
|
- z[3] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[4]) + xx16 + xx21 + t1 - t3 + t7);
|
|
|
- z[4] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[5]) - xx16 + t1 + t2 + t4);
|
|
|
- z[5] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[6]) + xx18 - xx17 + t2 + t3);
|
|
|
- z[6] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[7]) + xx16 + xx19 - xx18 + t3);
|
|
|
- z[7] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[8]) + xx16 + xx17 + xx20 - xx19);
|
|
|
- z[8] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[9]) + xx18 - xx20 + t4);
|
|
|
- z[9] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[10]) + xx18 + xx19 - t5 + t6);
|
|
|
- z[10] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (Int64(xx[11]) + xx19 + xx20 - t6);
|
|
|
- z[11] := UInt32(cc);
|
|
|
- cc := TBitOperations.Asr64(cc, 32);
|
|
|
- cc := cc + (n);
|
|
|
-
|
|
|
-{$IFDEF DEBUG}
|
|
|
- System.Assert(cc >= 0);
|
|
|
-{$ENDIF DEBUG}
|
|
|
- Reduce32(UInt32(cc), z);
|
|
|
-end;
|
|
|
-
|
|
|
-class procedure TSecP384R1Field.Multiply(const x, y, z: TCryptoLibUInt32Array);
|
|
|
+ LD: UInt32;
|
|
|
+ LI: Int32;
|
|
|
+begin
|
|
|
+ LD := 0;
|
|
|
+ for LI := 0 to 11 do
|
|
|
+ LD := LD or AX[LI];
|
|
|
+ LD := (LD shr 1) or (LD and 1);
|
|
|
+ Result := TBitOperations.Asr32(Int32(LD) - 1, 31);
|
|
|
+end;
|
|
|
+
|
|
|
+class procedure TSecP384R1Field.Multiply(const AX, AY, AZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- tt: TCryptoLibUInt32Array;
|
|
|
+ LTT: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- tt := TNat.Create(24);
|
|
|
- TNat384.Mul(x, y, tt);
|
|
|
- Reduce(tt, z);
|
|
|
+ LTT := TNat.Create(24);
|
|
|
+ TNat384.Mul(AX, AY, LTT);
|
|
|
+ Reduce(LTT, AZ);
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.Negate(const x, z: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.Multiply(const AX, AY, AZ, ATT: TCryptoLibUInt32Array);
|
|
|
begin
|
|
|
- if (TNat.IsZero(12, x)) then
|
|
|
- begin
|
|
|
- TNat.Zero(12, z);
|
|
|
- end
|
|
|
+ TNat384.Mul(AX, AY, ATT);
|
|
|
+ Reduce(ATT, AZ);
|
|
|
+end;
|
|
|
+
|
|
|
+class procedure TSecP384R1Field.Negate(const AX, AZ: TCryptoLibUInt32Array);
|
|
|
+begin
|
|
|
+ if IsZero(AX) <> 0 then
|
|
|
+ TNat.Sub(12, FP, FP, AZ)
|
|
|
else
|
|
|
- begin
|
|
|
- TNat.Sub(12, FP, x, z);
|
|
|
- end;
|
|
|
+ TNat.Sub(12, FP, AX, AZ);
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.Square(const x, z: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.Random(const AR: ISecureRandom; const AZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- tt: TCryptoLibUInt32Array;
|
|
|
+ LBB: TCryptoLibByteArray;
|
|
|
+begin
|
|
|
+ System.SetLength(LBB, 12 * 4);
|
|
|
+ repeat
|
|
|
+ AR.NextBytes(LBB);
|
|
|
+ TPack.LE_To_UInt32(LBB, 0, AZ, 0, 12);
|
|
|
+ until TNat.LessThan(12, AZ, FP) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class procedure TSecP384R1Field.RandomMult(const AR: ISecureRandom; const AZ: TCryptoLibUInt32Array);
|
|
|
begin
|
|
|
- tt := TNat.Create(24);
|
|
|
- TNat384.Square(x, tt);
|
|
|
- Reduce(tt, z);
|
|
|
+ repeat
|
|
|
+ Random(AR, AZ);
|
|
|
+ until IsZero(AZ) <> 0;
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.SquareN(const x: TCryptoLibUInt32Array;
|
|
|
- n: Int32; const z: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.Reduce(const AXX, AZ: TCryptoLibUInt32Array);
|
|
|
+var
|
|
|
+ LXX16, LXX17, LXX18, LXX19, LXX20, LXX21, LXX22, LXX23: Int64;
|
|
|
+ LT0, LT1, LT2, LT3, LT4, LT5, LT6, LT7: Int64;
|
|
|
+ LCc: Int64;
|
|
|
+ LN: Int64;
|
|
|
+begin
|
|
|
+ LN := 1;
|
|
|
+ LXX16 := Int64(UInt32(AXX[16]));
|
|
|
+ LXX17 := Int64(UInt32(AXX[17]));
|
|
|
+ LXX18 := Int64(UInt32(AXX[18]));
|
|
|
+ LXX19 := Int64(UInt32(AXX[19]));
|
|
|
+ LXX20 := Int64(UInt32(AXX[20]));
|
|
|
+ LXX21 := Int64(UInt32(AXX[21]));
|
|
|
+ LXX22 := Int64(UInt32(AXX[22]));
|
|
|
+ LXX23 := Int64(UInt32(AXX[23]));
|
|
|
+
|
|
|
+ LT0 := Int64(AXX[12]) + LXX20 - LN;
|
|
|
+ LT1 := Int64(AXX[13]) + LXX22;
|
|
|
+ LT2 := Int64(AXX[14]) + LXX22 + LXX23;
|
|
|
+ LT3 := Int64(AXX[15]) + LXX23;
|
|
|
+ LT4 := LXX17 + LXX21;
|
|
|
+ LT5 := LXX21 - LXX23;
|
|
|
+ LT6 := LXX22 - LXX23;
|
|
|
+ LT7 := LT0 + LT5;
|
|
|
+
|
|
|
+ LCc := 0;
|
|
|
+ LCc := LCc + (Int64(AXX[0]) + LT7);
|
|
|
+ AZ[0] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[1]) + LXX23 - LT0 + LT1);
|
|
|
+ AZ[1] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[2]) - LXX21 - LT1 + LT2);
|
|
|
+ AZ[2] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[3]) - LT2 + LT3 + LT7);
|
|
|
+ AZ[3] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[4]) + LXX16 + LXX21 + LT1 - LT3 + LT7);
|
|
|
+ AZ[4] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[5]) - LXX16 + LT1 + LT2 + LT4);
|
|
|
+ AZ[5] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[6]) + LXX18 - LXX17 + LT2 + LT3);
|
|
|
+ AZ[6] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[7]) + LXX16 + LXX19 - LXX18 + LT3);
|
|
|
+ AZ[7] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[8]) + LXX16 + LXX17 + LXX20 - LXX19);
|
|
|
+ AZ[8] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[9]) + LXX18 - LXX20 + LT4);
|
|
|
+ AZ[9] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[10]) + LXX18 + LXX19 - LT5 + LT6);
|
|
|
+ AZ[10] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AXX[11]) + LXX19 + LXX20 - LT6);
|
|
|
+ AZ[11] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + LN;
|
|
|
+
|
|
|
+ {$IFDEF DEBUG}
|
|
|
+ Assert(LCc >= 0);
|
|
|
+ {$ENDIF DEBUG}
|
|
|
+
|
|
|
+ Reduce32(UInt32(LCc), AZ);
|
|
|
+end;
|
|
|
+
|
|
|
+class procedure TSecP384R1Field.Reduce32(AX: UInt32; const AZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- tt: TCryptoLibUInt32Array;
|
|
|
+ LCc: Int64;
|
|
|
+ LXX12: Int64;
|
|
|
begin
|
|
|
-{$IFDEF DEBUG}
|
|
|
- System.Assert(n > 0);
|
|
|
-{$ENDIF DEBUG}
|
|
|
- tt := TNat.Create(24);
|
|
|
- TNat384.Square(x, tt);
|
|
|
- Reduce(tt, z);
|
|
|
+ LCc := 0;
|
|
|
|
|
|
- System.Dec(n);
|
|
|
- while (n > 0) do
|
|
|
+ if AX <> 0 then
|
|
|
begin
|
|
|
- TNat384.Square(z, tt);
|
|
|
- Reduce(tt, z);
|
|
|
- System.Dec(n);
|
|
|
+ LXX12 := Int64(AX);
|
|
|
+
|
|
|
+ LCc := LCc + (Int64(AZ[0]) + LXX12);
|
|
|
+ AZ[0] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AZ[1]) - LXX12);
|
|
|
+ AZ[1] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ if LCc <> 0 then
|
|
|
+ begin
|
|
|
+ LCc := LCc + Int64(AZ[2]);
|
|
|
+ AZ[2] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ end;
|
|
|
+ LCc := LCc + (Int64(AZ[3]) + LXX12);
|
|
|
+ AZ[3] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+ LCc := LCc + (Int64(AZ[4]) + LXX12);
|
|
|
+ AZ[4] := UInt32(LCc);
|
|
|
+ LCc := TBitOperations.Asr64(LCc, 32);
|
|
|
+
|
|
|
+ {$IFDEF DEBUG}
|
|
|
+ Assert((LCc = 0) or (LCc = 1));
|
|
|
+ {$ENDIF DEBUG}
|
|
|
end;
|
|
|
+
|
|
|
+ if ((LCc <> 0) and (TNat.IncAt(12, AZ, 5) <> 0)) or
|
|
|
+ ((AZ[11] = P11) and TNat.Gte(12, AZ, FP)) then
|
|
|
+ AddPInvTo(AZ);
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.Subtract(const x, y, z: TCryptoLibUInt32Array);
|
|
|
+class procedure TSecP384R1Field.Square(const AX, AZ: TCryptoLibUInt32Array);
|
|
|
var
|
|
|
- c: Int32;
|
|
|
+ LTT: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- c := TNat.Sub(12, x, y, z);
|
|
|
- if (c <> 0) then
|
|
|
- begin
|
|
|
- SubPInvFrom(z);
|
|
|
- end;
|
|
|
+ LTT := TNat.Create(24);
|
|
|
+ TNat384.Square(AX, LTT);
|
|
|
+ Reduce(LTT, AZ);
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.SubtractExt(const xx, yy,
|
|
|
- zz: TCryptoLibUInt32Array);
|
|
|
-var
|
|
|
- c: Int32;
|
|
|
+class procedure TSecP384R1Field.Square(const AX, AZ, ATT: TCryptoLibUInt32Array);
|
|
|
begin
|
|
|
- c := TNat.Sub(24, xx, yy, zz);
|
|
|
- if (c <> 0) then
|
|
|
+ TNat384.Square(AX, ATT);
|
|
|
+ Reduce(ATT, AZ);
|
|
|
+end;
|
|
|
+
|
|
|
+class procedure TSecP384R1Field.SquareN(const AX: TCryptoLibUInt32Array; AN: Int32;
|
|
|
+ const AZ: TCryptoLibUInt32Array);
|
|
|
+var
|
|
|
+ LTT: TCryptoLibUInt32Array;
|
|
|
+begin
|
|
|
+ {$IFDEF DEBUG}
|
|
|
+ Assert(AN > 0);
|
|
|
+ {$ENDIF DEBUG}
|
|
|
+ LTT := TNat.Create(24);
|
|
|
+ TNat384.Square(AX, LTT);
|
|
|
+ Reduce(LTT, AZ);
|
|
|
+ Dec(AN);
|
|
|
+ while AN > 0 do
|
|
|
begin
|
|
|
- if (TNat.SubFrom(System.Length(FPExtInv), FPExtInv, zz) <> 0) then
|
|
|
- begin
|
|
|
- TNat.DecAt(24, zz, System.Length(FPExtInv));
|
|
|
- end;
|
|
|
+ TNat384.Square(AZ, LTT);
|
|
|
+ Reduce(LTT, AZ);
|
|
|
+ Dec(AN);
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-class procedure TSecP384R1Field.Twice(const x, z: TCryptoLibUInt32Array);
|
|
|
-var
|
|
|
- c: UInt32;
|
|
|
+class procedure TSecP384R1Field.SquareN(const AX: TCryptoLibUInt32Array; AN: Int32;
|
|
|
+ const AZ, ATT: TCryptoLibUInt32Array);
|
|
|
begin
|
|
|
- c := TNat.ShiftUpBit(12, x, 0, z);
|
|
|
- if ((c <> 0) or ((z[11] = P11) and (TNat.Gte(12, z, FP)))) then
|
|
|
+ {$IFDEF DEBUG}
|
|
|
+ Assert(AN > 0);
|
|
|
+ {$ENDIF DEBUG}
|
|
|
+ TNat384.Square(AX, ATT);
|
|
|
+ Reduce(ATT, AZ);
|
|
|
+ Dec(AN);
|
|
|
+ while AN > 0 do
|
|
|
begin
|
|
|
- AddPInvTo(z);
|
|
|
+ TNat384.Square(AZ, ATT);
|
|
|
+ Reduce(ATT, AZ);
|
|
|
+ Dec(AN);
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-{ TSecP384R1FieldElement }
|
|
|
-
|
|
|
-class function TSecP384R1FieldElement.GetQ: TBigInteger;
|
|
|
+class procedure TSecP384R1Field.Subtract(const AX, AY, AZ: TCryptoLibUInt32Array);
|
|
|
+var
|
|
|
+ LC: Int32;
|
|
|
begin
|
|
|
- result := TBigInteger.Create(1,
|
|
|
- THex.Decode
|
|
|
- ('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF')
|
|
|
- );
|
|
|
+ LC := TNat.Sub(12, AX, AY, AZ);
|
|
|
+ if LC <> 0 then
|
|
|
+ SubPInvFrom(AZ);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.GetX: TCryptoLibUInt32Array;
|
|
|
+class procedure TSecP384R1Field.SubtractExt(const AXX, AYY, AZZ: TCryptoLibUInt32Array);
|
|
|
+var
|
|
|
+ LC: Int32;
|
|
|
begin
|
|
|
- result := Fx;
|
|
|
+ LC := TNat.Sub(24, AXX, AYY, AZZ);
|
|
|
+ if LC <> 0 then
|
|
|
+ if TNat.SubFrom(System.Length(FPExtInv), FPExtInv, AZZ) <> 0 then
|
|
|
+ TNat.DecAt(24, AZZ, System.Length(FPExtInv));
|
|
|
end;
|
|
|
|
|
|
-constructor TSecP384R1FieldElement.Create;
|
|
|
+class procedure TSecP384R1Field.Twice(const AX, AZ: TCryptoLibUInt32Array);
|
|
|
+var
|
|
|
+ LC: UInt32;
|
|
|
begin
|
|
|
- Inherited Create();
|
|
|
- Fx := TNat.Create(12);
|
|
|
+ LC := TNat.ShiftUpBit(12, AX, 0, AZ);
|
|
|
+ if (LC <> 0) or ((AZ[11] = P11) and TNat.Gte(12, AZ, FP)) then
|
|
|
+ AddPInvTo(AZ);
|
|
|
end;
|
|
|
|
|
|
-constructor TSecP384R1FieldElement.Create(const x: TBigInteger);
|
|
|
+{ TSecP384R1FieldElement }
|
|
|
+
|
|
|
+class procedure TSecP384R1FieldElement.Boot;
|
|
|
begin
|
|
|
- if ((not(x.IsInitialized)) or (x.SignValue < 0) or (x.CompareTo(Q) >= 0)) then
|
|
|
- begin
|
|
|
- raise EArgumentCryptoLibException.CreateResFmt
|
|
|
- (@SInvalidValueForSecP384R1FieldElement, ['x']);
|
|
|
- end;
|
|
|
- Inherited Create();
|
|
|
- Fx := TSecP384R1Field.FromBigInteger(x);
|
|
|
+ FQ := TBigInteger.Create(1, THex.Decode('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF'));
|
|
|
end;
|
|
|
|
|
|
-constructor TSecP384R1FieldElement.Create(const x: TCryptoLibUInt32Array);
|
|
|
+class constructor TSecP384R1FieldElement.Create;
|
|
|
begin
|
|
|
- Inherited Create();
|
|
|
- Fx := x;
|
|
|
+ Boot;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.GetFieldName: string;
|
|
|
+class function TSecP384R1FieldElement.GetQ: TBigInteger;
|
|
|
begin
|
|
|
- result := 'SecP384R1Field';
|
|
|
+ Result := FQ;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.GetFieldSize: Int32;
|
|
|
+constructor TSecP384R1FieldElement.Create(const AX: TBigInteger);
|
|
|
begin
|
|
|
- result := Q.BitLength;
|
|
|
+ Inherited Create;
|
|
|
+ if (not AX.IsInitialized) or (AX.SignValue < 0) or (AX.CompareTo(FQ) >= 0) then
|
|
|
+ raise EArgumentCryptoLibException.CreateRes(@SInvalidSecP384R1FieldElement);
|
|
|
+ FX := TSecP384R1Field.FromBigInteger(AX);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
|
|
|
-{$ENDIF DELPHI}
|
|
|
+constructor TSecP384R1FieldElement.Create();
|
|
|
begin
|
|
|
- result := Q.GetHashCode() xor TArrayUtilities.GetArrayHashCode(Fx, 0, 12);
|
|
|
+ Inherited Create;
|
|
|
+ FX := TNat.Create(12);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.GetIsOne: Boolean;
|
|
|
+constructor TSecP384R1FieldElement.Create(const AX: TCryptoLibUInt32Array);
|
|
|
begin
|
|
|
- result := TNat.IsOne(12, Fx);
|
|
|
+ Inherited Create;
|
|
|
+ FX := AX;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.GetIsZero: Boolean;
|
|
|
+function TSecP384R1FieldElement.GetX: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- result := TNat.IsZero(12, Fx);
|
|
|
+ Result := FX;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.Sqrt: IECFieldElement;
|
|
|
-var
|
|
|
- x1, t1, t2, t3, t4, r: TCryptoLibUInt32Array;
|
|
|
+function TSecP384R1FieldElement.GetFieldName: String;
|
|
|
begin
|
|
|
- // Raise this element to the exponent 2^382 - 2^126 - 2^94 + 2^30
|
|
|
- x1 := Fx;
|
|
|
- if ((TNat.IsZero(12, x1)) or (TNat.IsOne(12, x1))) then
|
|
|
- begin
|
|
|
- result := Self as IECFieldElement;
|
|
|
- Exit;
|
|
|
- end;
|
|
|
-
|
|
|
- t1 := TNat.Create(12);
|
|
|
- t2 := TNat.Create(12);
|
|
|
- t3 := TNat.Create(12);
|
|
|
- t4 := TNat.Create(12);
|
|
|
-
|
|
|
- TSecP384R1Field.Square(x1, t1);
|
|
|
- TSecP384R1Field.Multiply(t1, x1, t1);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(t1, 2, t2);
|
|
|
- TSecP384R1Field.Multiply(t2, t1, t2);
|
|
|
-
|
|
|
- TSecP384R1Field.Square(t2, t2);
|
|
|
- TSecP384R1Field.Multiply(t2, x1, t2);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(t2, 5, t3);
|
|
|
- TSecP384R1Field.Multiply(t3, t2, t3);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(t3, 5, t4);
|
|
|
- TSecP384R1Field.Multiply(t4, t2, t4);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(t4, 15, t2);
|
|
|
- TSecP384R1Field.Multiply(t2, t4, t2);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(t2, 2, t3);
|
|
|
- TSecP384R1Field.Multiply(t1, t3, t1);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(t3, 28, t3);
|
|
|
- TSecP384R1Field.Multiply(t2, t3, t2);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(t2, 60, t3);
|
|
|
- TSecP384R1Field.Multiply(t3, t2, t3);
|
|
|
-
|
|
|
- r := t2;
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(t3, 120, r);
|
|
|
- TSecP384R1Field.Multiply(r, t3, r);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(r, 15, r);
|
|
|
- TSecP384R1Field.Multiply(r, t4, r);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(r, 33, r);
|
|
|
- TSecP384R1Field.Multiply(r, t1, r);
|
|
|
-
|
|
|
- TSecP384R1Field.SquareN(r, 64, r);
|
|
|
- TSecP384R1Field.Multiply(r, x1, r);
|
|
|
+ Result := 'SecP384R1Field';
|
|
|
+end;
|
|
|
|
|
|
- TSecP384R1Field.SquareN(r, 30, t1);
|
|
|
- TSecP384R1Field.Square(t1, t2);
|
|
|
+function TSecP384R1FieldElement.GetFieldSize: Int32;
|
|
|
+begin
|
|
|
+ Result := FQ.BitLength;
|
|
|
+end;
|
|
|
|
|
|
- if TNat.Eq(12, x1, t2) then
|
|
|
- begin
|
|
|
- result := TSecP384R1FieldElement.Create(t1);
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- result := Nil;
|
|
|
- end;
|
|
|
+function TSecP384R1FieldElement.GetIsOne: Boolean;
|
|
|
+begin
|
|
|
+ Result := TNat.IsOne(12, FX);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.TestBitZero: Boolean;
|
|
|
+function TSecP384R1FieldElement.GetIsZero: Boolean;
|
|
|
begin
|
|
|
- result := TNat.GetBit(Fx, 0) = 1;
|
|
|
+ Result := TNat.IsZero(12, FX);
|
|
|
end;
|
|
|
|
|
|
function TSecP384R1FieldElement.ToBigInteger: TBigInteger;
|
|
|
begin
|
|
|
- result := TNat.ToBigInteger(12, Fx);
|
|
|
+ Result := TNat.ToBigInteger(12, FX);
|
|
|
+end;
|
|
|
+
|
|
|
+function TSecP384R1FieldElement.TestBitZero: Boolean;
|
|
|
+begin
|
|
|
+ Result := TNat.GetBit(FX, 0) = 1;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.Add(const b: IECFieldElement): IECFieldElement;
|
|
|
+function TSecP384R1FieldElement.Add(const AB: IECFieldElement): IECFieldElement;
|
|
|
var
|
|
|
- z: TCryptoLibUInt32Array;
|
|
|
+ LZ: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- z := TNat.Create(12);
|
|
|
- TSecP384R1Field.Add(Fx, (b as ISecP384R1FieldElement).x, z);
|
|
|
- result := TSecP384R1FieldElement.Create(z);
|
|
|
+ LZ := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Add(FX, (AB as ISecP384R1FieldElement).X, LZ);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LZ);
|
|
|
end;
|
|
|
|
|
|
function TSecP384R1FieldElement.AddOne: IECFieldElement;
|
|
|
var
|
|
|
- z: TCryptoLibUInt32Array;
|
|
|
+ LZ: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- z := TNat.Create(12);
|
|
|
- TSecP384R1Field.AddOne(Fx, z);
|
|
|
- result := TSecP384R1FieldElement.Create(z);
|
|
|
+ LZ := TNat.Create(12);
|
|
|
+ TSecP384R1Field.AddOne(FX, LZ);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LZ);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.Subtract(const b: IECFieldElement)
|
|
|
- : IECFieldElement;
|
|
|
+function TSecP384R1FieldElement.Subtract(const AB: IECFieldElement): IECFieldElement;
|
|
|
var
|
|
|
- z: TCryptoLibUInt32Array;
|
|
|
+ LZ: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- z := TNat.Create(12);
|
|
|
- TSecP384R1Field.Subtract(Fx, (b as ISecP384R1FieldElement).x, z);
|
|
|
- result := TSecP384R1FieldElement.Create(z);
|
|
|
+ LZ := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Subtract(FX, (AB as ISecP384R1FieldElement).X, LZ);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LZ);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.Multiply(const b: IECFieldElement)
|
|
|
- : IECFieldElement;
|
|
|
+function TSecP384R1FieldElement.Multiply(const AB: IECFieldElement): IECFieldElement;
|
|
|
var
|
|
|
- z: TCryptoLibUInt32Array;
|
|
|
+ LZ: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- z := TNat.Create(12);
|
|
|
- TSecP384R1Field.Multiply(Fx, (b as ISecP384R1FieldElement).x, z);
|
|
|
- result := TSecP384R1FieldElement.Create(z);
|
|
|
+ LZ := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Multiply(FX, (AB as ISecP384R1FieldElement).X, LZ);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LZ);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.Divide(const b: IECFieldElement)
|
|
|
- : IECFieldElement;
|
|
|
+function TSecP384R1FieldElement.Divide(const AB: IECFieldElement): IECFieldElement;
|
|
|
var
|
|
|
- z: TCryptoLibUInt32Array;
|
|
|
+ LZ: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- z := TNat.Create(12);
|
|
|
- TMod.CheckedModOddInverse(TSecP384R1Field.P, (b as ISecP384R1FieldElement).x, z);
|
|
|
- TSecP384R1Field.Multiply(z, Fx, z);
|
|
|
- result := TSecP384R1FieldElement.Create(z);
|
|
|
+ LZ := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Inv((AB as ISecP384R1FieldElement).X, LZ);
|
|
|
+ TSecP384R1Field.Multiply(LZ, FX, LZ);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LZ);
|
|
|
end;
|
|
|
|
|
|
function TSecP384R1FieldElement.Negate: IECFieldElement;
|
|
|
var
|
|
|
- z: TCryptoLibUInt32Array;
|
|
|
+ LZ: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- z := TNat.Create(12);
|
|
|
- TSecP384R1Field.Negate(Fx, z);
|
|
|
- result := TSecP384R1FieldElement.Create(z);
|
|
|
+ LZ := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Negate(FX, LZ);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LZ);
|
|
|
end;
|
|
|
|
|
|
function TSecP384R1FieldElement.Square: IECFieldElement;
|
|
|
var
|
|
|
- z: TCryptoLibUInt32Array;
|
|
|
+ LZ: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- z := TNat.Create(12);
|
|
|
- TSecP384R1Field.Square(Fx, z);
|
|
|
- result := TSecP384R1FieldElement.Create(z);
|
|
|
+ LZ := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Square(FX, LZ);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LZ);
|
|
|
end;
|
|
|
|
|
|
function TSecP384R1FieldElement.Invert: IECFieldElement;
|
|
|
var
|
|
|
- z: TCryptoLibUInt32Array;
|
|
|
+ LZ: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- z := TNat.Create(12);
|
|
|
- TMod.CheckedModOddInverse(TSecP384R1Field.P, Fx, z);
|
|
|
- result := TSecP384R1FieldElement.Create(z);
|
|
|
+ LZ := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Inv(FX, LZ);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LZ);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1FieldElement.Equals(const AOther: ISecP384R1FieldElement): Boolean;
|
|
|
+function TSecP384R1FieldElement.Sqrt: IECFieldElement;
|
|
|
+var
|
|
|
+ LX1, LTT0, LT1, LT2, LT3, LT4: TCryptoLibUInt32Array;
|
|
|
+ LR: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- if (Self as ISecP384R1FieldElement) = AOther then
|
|
|
- Exit(True);
|
|
|
- if AOther = nil then
|
|
|
- Exit(False);
|
|
|
- Result := TNat.Eq(12, Fx, AOther.x);
|
|
|
+ LX1 := FX;
|
|
|
+ if TNat.IsZero(12, LX1) or TNat.IsOne(12, LX1) then
|
|
|
+ Exit(Self as IECFieldElement);
|
|
|
+
|
|
|
+ LTT0 := TNat.Create(24);
|
|
|
+ LT1 := TNat.Create(12);
|
|
|
+ LT2 := TNat.Create(12);
|
|
|
+ LT3 := TNat.Create(12);
|
|
|
+ LT4 := TNat.Create(12);
|
|
|
+
|
|
|
+ TSecP384R1Field.Square(LX1, LT1, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LT1, LX1, LT1, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LT1, 2, LT2, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LT2, LT1, LT2, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.Square(LT2, LT2, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LT2, LX1, LT2, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LT2, 5, LT3, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LT3, LT2, LT3, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LT3, 5, LT4, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LT4, LT2, LT4, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LT4, 15, LT2, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LT2, LT4, LT2, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LT2, 2, LT3, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LT1, LT3, LT1, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LT3, 28, LT3, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LT2, LT3, LT2, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LT2, 60, LT3, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LT3, LT2, LT3, LTT0);
|
|
|
+
|
|
|
+ LR := LT2;
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LT3, 120, LR, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LR, LT3, LR, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LR, 15, LR, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LR, LT4, LR, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LR, 33, LR, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LR, LT1, LR, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LR, 64, LR, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LR, LX1, LR, LTT0);
|
|
|
+
|
|
|
+ TSecP384R1Field.SquareN(LR, 30, LT1, LTT0);
|
|
|
+ TSecP384R1Field.Square(LT1, LT2, LTT0);
|
|
|
+
|
|
|
+ if TNat.Eq(12, LX1, LT2) then
|
|
|
+ Result := TSecP384R1FieldElement.Create(LT1)
|
|
|
+ else
|
|
|
+ Result := nil;
|
|
|
end;
|
|
|
|
|
|
function TSecP384R1FieldElement.Equals(const AOther: IECFieldElement): Boolean;
|
|
|
-var
|
|
|
- LSec: ISecP384R1FieldElement;
|
|
|
begin
|
|
|
+ if (Self as IECFieldElement) = AOther then
|
|
|
+ Exit(True);
|
|
|
if AOther = nil then
|
|
|
Exit(False);
|
|
|
- if Supports(AOther, ISecP384R1FieldElement, LSec) then
|
|
|
- Result := Equals(LSec)
|
|
|
- else
|
|
|
- Result := ToBigInteger.Equals(AOther.ToBigInteger);
|
|
|
+ Result := TNat.Eq(12, FX, (AOther as ISecP384R1FieldElement).X);
|
|
|
+end;
|
|
|
+
|
|
|
+function TSecP384R1FieldElement.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt; {$ENDIF DELPHI}
|
|
|
+begin
|
|
|
+ Result := FQ.GetHashCode() xor TArrayUtilities.GetArrayHashCode(FX, 0, 12);
|
|
|
end;
|
|
|
|
|
|
{ TSecP384R1Point }
|
|
|
|
|
|
-constructor TSecP384R1Point.Create(const curve: IECCurve;
|
|
|
- const x, y: IECFieldElement);
|
|
|
+constructor TSecP384R1Point.Create(const ACurve: IECCurve; const AX, AY: IECFieldElement);
|
|
|
begin
|
|
|
- Create(curve, x, y, false);
|
|
|
+ Inherited Create(ACurve, AX, AY);
|
|
|
end;
|
|
|
|
|
|
-constructor TSecP384R1Point.Create(const curve: IECCurve;
|
|
|
- const x, y: IECFieldElement; withCompression: Boolean);
|
|
|
+constructor TSecP384R1Point.Create(const ACurve: IECCurve; const AX, AY: IECFieldElement;
|
|
|
+ const AZs: TCryptoLibGenericArray<IECFieldElement>);
|
|
|
begin
|
|
|
- Inherited Create(curve, x, y, withCompression);
|
|
|
- if ((x = Nil) <> (y = Nil)) then
|
|
|
- begin
|
|
|
- raise EArgumentCryptoLibException.CreateRes(@SOneOfECFieldElementIsNil);
|
|
|
- end;
|
|
|
+ Inherited Create(ACurve, AX, AY, AZs);
|
|
|
end;
|
|
|
|
|
|
-constructor TSecP384R1Point.Create(const curve: IECCurve;
|
|
|
- const x, y: IECFieldElement;
|
|
|
- const zs: TCryptoLibGenericArray<IECFieldElement>; withCompression: Boolean);
|
|
|
+function TSecP384R1Point.Detach: IECPoint;
|
|
|
begin
|
|
|
- Inherited Create(curve, x, y, zs, withCompression);
|
|
|
+ Result := TSecP384R1Point.Create(nil, AffineXCoord, AffineYCoord);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Point.Add(const b: IECPoint): IECPoint;
|
|
|
+function TSecP384R1Point.Add(const AB: IECPoint): IECPoint;
|
|
|
var
|
|
|
- Lcurve: IECCurve;
|
|
|
- x1, Y1, X2, Y2, Z1, Z2, X3, Y3, Z3: ISecP384R1FieldElement;
|
|
|
- c: UInt32;
|
|
|
- tt1, tt2, t3, t4, U2, S2, U1, S1, H, r, HSquared, G, V: TCryptoLibUInt32Array;
|
|
|
- Z1IsOne, Z2IsOne: Boolean;
|
|
|
- zs: TCryptoLibGenericArray<IECFieldElement>;
|
|
|
-begin
|
|
|
- if (IsInfinity) then
|
|
|
+ LCurve: IECCurve;
|
|
|
+ LX1, LY1, LX2, LY2, LZ1, LZ2: ISecP384R1FieldElement;
|
|
|
+ LTT0, LTT1, LTT2: TCryptoLibUInt32Array;
|
|
|
+ LT3, LT4: TCryptoLibUInt32Array;
|
|
|
+ LZ1IsOne, LZ2IsOne: Boolean;
|
|
|
+ LU2, LS2, LU1, LS1: TCryptoLibUInt32Array;
|
|
|
+ LH, LR, LHSquared, LG, LV: TCryptoLibUInt32Array;
|
|
|
+ LC: UInt32;
|
|
|
+ LX3, LY3, LZ3: ISecP384R1FieldElement;
|
|
|
+ LZs: TCryptoLibGenericArray<IECFieldElement>;
|
|
|
+begin
|
|
|
+ if IsInfinity then
|
|
|
+ Exit(AB);
|
|
|
+ if AB.IsInfinity then
|
|
|
+ Exit(Self as IECPoint);
|
|
|
+ if (Self as IECPoint) = AB then
|
|
|
+ Exit(Twice());
|
|
|
+
|
|
|
+ LCurve := Curve;
|
|
|
+ LX1 := RawXCoord as ISecP384R1FieldElement;
|
|
|
+ LY1 := RawYCoord as ISecP384R1FieldElement;
|
|
|
+ LX2 := AB.RawXCoord as ISecP384R1FieldElement;
|
|
|
+ LY2 := AB.RawYCoord as ISecP384R1FieldElement;
|
|
|
+ LZ1 := RawZCoords[0] as ISecP384R1FieldElement;
|
|
|
+ LZ2 := AB.GetZCoord(0) as ISecP384R1FieldElement;
|
|
|
+
|
|
|
+ LTT0 := TNat.Create(24);
|
|
|
+ LTT1 := TNat.Create(24);
|
|
|
+ LTT2 := TNat.Create(24);
|
|
|
+ LT3 := TNat.Create(12);
|
|
|
+ LT4 := TNat.Create(12);
|
|
|
+
|
|
|
+ LZ1IsOne := LZ1.IsOne;
|
|
|
+ if LZ1IsOne then
|
|
|
begin
|
|
|
- result := b;
|
|
|
- Exit;
|
|
|
- end;
|
|
|
- if (b.IsInfinity) then
|
|
|
+ LU2 := LX2.X;
|
|
|
+ LS2 := LY2.X;
|
|
|
+ end
|
|
|
+ else
|
|
|
begin
|
|
|
- result := Self as IECPoint;
|
|
|
- Exit;
|
|
|
+ LS2 := LT3;
|
|
|
+ TSecP384R1Field.Square(LZ1.X, LS2, LTT0);
|
|
|
+ LU2 := LTT2;
|
|
|
+ TSecP384R1Field.Multiply(LS2, LX2.X, LU2, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LS2, LZ1.X, LS2, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LS2, LY2.X, LS2, LTT0);
|
|
|
end;
|
|
|
- if ((Self as IECPoint) = b) then
|
|
|
+
|
|
|
+ LZ2IsOne := LZ2.IsOne;
|
|
|
+ if LZ2IsOne then
|
|
|
+ begin
|
|
|
+ LU1 := LX1.X;
|
|
|
+ LS1 := LY1.X;
|
|
|
+ end
|
|
|
+ else
|
|
|
begin
|
|
|
- result := Twice();
|
|
|
- Exit;
|
|
|
+ LS1 := LT4;
|
|
|
+ TSecP384R1Field.Square(LZ2.X, LS1, LTT0);
|
|
|
+ LU1 := LTT1;
|
|
|
+ TSecP384R1Field.Multiply(LS1, LX1.X, LU1, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LS1, LZ2.X, LS1, LTT0);
|
|
|
+ TSecP384R1Field.Multiply(LS1, LY1.X, LS1, LTT0);
|
|
|
end;
|
|
|
|
|
|
- Lcurve := curve;
|
|
|
-
|
|
|
- x1 := RawXCoord as ISecP384R1FieldElement;
|
|
|
- Y1 := RawYCoord as ISecP384R1FieldElement;
|
|
|
- X2 := b.RawXCoord as ISecP384R1FieldElement;
|
|
|
- Y2 := b.RawYCoord as ISecP384R1FieldElement;
|
|
|
+ LH := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Subtract(LU1, LU2, LH);
|
|
|
|
|
|
- Z1 := RawZCoords[0] as ISecP384R1FieldElement;
|
|
|
- Z2 := b.RawZCoords[0] as ISecP384R1FieldElement;
|
|
|
+ LR := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Subtract(LS1, LS2, LR);
|
|
|
|
|
|
- tt1 := TNat.Create(24);
|
|
|
- tt2 := TNat.Create(24);
|
|
|
- t3 := TNat.Create(12);
|
|
|
- t4 := TNat.Create(12);
|
|
|
+ if TNat.IsZero(12, LH) then
|
|
|
+ begin
|
|
|
+ if TNat.IsZero(12, LR) then
|
|
|
+ Exit(Twice());
|
|
|
+ Exit(LCurve.Infinity);
|
|
|
+ end;
|
|
|
|
|
|
- Z1IsOne := Z1.IsOne;
|
|
|
+ LHSquared := LT3;
|
|
|
+ TSecP384R1Field.Square(LH, LHSquared, LTT0);
|
|
|
|
|
|
- if (Z1IsOne) then
|
|
|
- begin
|
|
|
- U2 := X2.x;
|
|
|
- S2 := Y2.x;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- S2 := t3;
|
|
|
- TSecP384R1Field.Square(Z1.x, S2);
|
|
|
+ LG := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Multiply(LHSquared, LH, LG, LTT0);
|
|
|
|
|
|
- U2 := tt2;
|
|
|
- TSecP384R1Field.Multiply(S2, X2.x, U2);
|
|
|
+ LV := LT3;
|
|
|
+ TSecP384R1Field.Multiply(LHSquared, LU1, LV, LTT0);
|
|
|
|
|
|
- TSecP384R1Field.Multiply(S2, Z1.x, S2);
|
|
|
- TSecP384R1Field.Multiply(S2, Y2.x, S2);
|
|
|
- end;
|
|
|
+ TSecP384R1Field.Negate(LG, LG);
|
|
|
+ TNat384.Mul(LS1, LG, LTT1);
|
|
|
|
|
|
- Z2IsOne := Z2.IsOne;
|
|
|
- if (Z2IsOne) then
|
|
|
- begin
|
|
|
- U1 := x1.x;
|
|
|
- S1 := Y1.x;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- S1 := t4;
|
|
|
- TSecP384R1Field.Square(Z2.x, S1);
|
|
|
+ LC := TNat.AddBothTo(12, LV, LV, LG);
|
|
|
+ TSecP384R1Field.Reduce32(LC, LG);
|
|
|
|
|
|
- U1 := tt1;
|
|
|
- TSecP384R1Field.Multiply(S1, x1.x, U1);
|
|
|
+ LX3 := TSecP384R1FieldElement.Create(LT4);
|
|
|
+ TSecP384R1Field.Square(LR, LX3.X, LTT0);
|
|
|
+ TSecP384R1Field.Subtract(LX3.X, LG, LX3.X);
|
|
|
|
|
|
- TSecP384R1Field.Multiply(S1, Z2.x, S1);
|
|
|
- TSecP384R1Field.Multiply(S1, Y1.x, S1);
|
|
|
- end;
|
|
|
+ LY3 := TSecP384R1FieldElement.Create(LG);
|
|
|
+ TSecP384R1Field.Subtract(LV, LX3.X, LY3.X);
|
|
|
+ TNat384.Mul(LY3.X, LR, LTT2);
|
|
|
+ TSecP384R1Field.AddExt(LTT1, LTT2, LTT1);
|
|
|
+ TSecP384R1Field.Reduce(LTT1, LY3.X);
|
|
|
|
|
|
- H := TNat.Create(12);
|
|
|
- TSecP384R1Field.Subtract(U1, U2, H);
|
|
|
+ LZ3 := TSecP384R1FieldElement.Create(LH);
|
|
|
+ if not LZ1IsOne then
|
|
|
+ TSecP384R1Field.Multiply(LZ3.X, LZ1.X, LZ3.X, LTT0);
|
|
|
+ if not LZ2IsOne then
|
|
|
+ TSecP384R1Field.Multiply(LZ3.X, LZ2.X, LZ3.X, LTT0);
|
|
|
|
|
|
- r := TNat.Create(12);
|
|
|
- TSecP384R1Field.Subtract(S1, S2, r);
|
|
|
+ LZs := TCryptoLibGenericArray<IECFieldElement>.Create(LZ3 as IECFieldElement);
|
|
|
+ Result := TSecP384R1Point.Create(LCurve, LX3 as IECFieldElement, LY3 as IECFieldElement, LZs);
|
|
|
+end;
|
|
|
|
|
|
- // Check if b = Self or b = -Self
|
|
|
- if (TNat.IsZero(12, H)) then
|
|
|
+function TSecP384R1Point.Twice: IECPoint;
|
|
|
+var
|
|
|
+ LCurve: IECCurve;
|
|
|
+ LY1, LX1, LZ1: ISecP384R1FieldElement;
|
|
|
+ LTT0: TCryptoLibUInt32Array;
|
|
|
+ LY1Squared, LT, LT1, LT2: TCryptoLibUInt32Array;
|
|
|
+ LZ1Squared, LM, LS: TCryptoLibUInt32Array;
|
|
|
+ LZ1IsOne: Boolean;
|
|
|
+ LC: UInt32;
|
|
|
+ LX3, LY3, LZ3: ISecP384R1FieldElement;
|
|
|
+ LZs: TCryptoLibGenericArray<IECFieldElement>;
|
|
|
+begin
|
|
|
+ if IsInfinity then
|
|
|
+ Exit(Self as IECPoint);
|
|
|
+
|
|
|
+ LCurve := Curve;
|
|
|
+ LY1 := RawYCoord as ISecP384R1FieldElement;
|
|
|
+ if LY1.IsZero then
|
|
|
+ Exit(LCurve.Infinity);
|
|
|
+
|
|
|
+ LX1 := RawXCoord as ISecP384R1FieldElement;
|
|
|
+ LZ1 := RawZCoords[0] as ISecP384R1FieldElement;
|
|
|
+
|
|
|
+ LTT0 := TNat.Create(24);
|
|
|
+ LT1 := TNat.Create(12);
|
|
|
+ LT2 := TNat.Create(12);
|
|
|
+
|
|
|
+ LY1Squared := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Square(LY1.X, LY1Squared, LTT0);
|
|
|
+
|
|
|
+ LT := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Square(LY1Squared, LT, LTT0);
|
|
|
+
|
|
|
+ LZ1IsOne := LZ1.IsOne;
|
|
|
+ if LZ1IsOne then
|
|
|
+ LZ1Squared := LZ1.X
|
|
|
+ else
|
|
|
begin
|
|
|
- if (TNat.IsZero(12, r)) then
|
|
|
- begin
|
|
|
- // Self = b, i.e. Self must be doubled
|
|
|
- result := Twice();
|
|
|
- Exit;
|
|
|
- end;
|
|
|
-
|
|
|
- // Self = -b, i.e. the result is the point at infinity
|
|
|
- result := Lcurve.Infinity;
|
|
|
- Exit;
|
|
|
+ LZ1Squared := LT2;
|
|
|
+ TSecP384R1Field.Square(LZ1.X, LZ1Squared, LTT0);
|
|
|
end;
|
|
|
|
|
|
- HSquared := t3;
|
|
|
- TSecP384R1Field.Square(H, HSquared);
|
|
|
+ TSecP384R1Field.Subtract(LX1.X, LZ1Squared, LT1);
|
|
|
|
|
|
- G := TNat.Create(12);
|
|
|
- TSecP384R1Field.Multiply(HSquared, H, G);
|
|
|
+ LM := LT2;
|
|
|
+ TSecP384R1Field.Add(LX1.X, LZ1Squared, LM);
|
|
|
+ TSecP384R1Field.Multiply(LM, LT1, LM, LTT0);
|
|
|
+ LC := TNat.AddBothTo(12, LM, LM, LM);
|
|
|
+ TSecP384R1Field.Reduce32(LC, LM);
|
|
|
|
|
|
- V := t3;
|
|
|
- TSecP384R1Field.Multiply(HSquared, U1, V);
|
|
|
+ LS := LY1Squared;
|
|
|
+ TSecP384R1Field.Multiply(LY1Squared, LX1.X, LS, LTT0);
|
|
|
+ LC := TNat.ShiftUpBits(12, LS, 2, 0, LS);
|
|
|
+ TSecP384R1Field.Reduce32(LC, LS);
|
|
|
|
|
|
- TSecP384R1Field.Negate(G, G);
|
|
|
- TNat384.Mul(S1, G, tt1);
|
|
|
+ LC := TNat.ShiftUpBits(12, LT, 3, 0, LT1);
|
|
|
+ TSecP384R1Field.Reduce32(LC, LT1);
|
|
|
|
|
|
- c := TNat.AddBothTo(12, V, V, G);
|
|
|
- TSecP384R1Field.Reduce32(c, G);
|
|
|
+ LX3 := TSecP384R1FieldElement.Create(LT);
|
|
|
+ TSecP384R1Field.Square(LM, LX3.X, LTT0);
|
|
|
+ TSecP384R1Field.Subtract(LX3.X, LS, LX3.X);
|
|
|
+ TSecP384R1Field.Subtract(LX3.X, LS, LX3.X);
|
|
|
|
|
|
- X3 := TSecP384R1FieldElement.Create(t4);
|
|
|
- TSecP384R1Field.Square(r, X3.x);
|
|
|
- TSecP384R1Field.Subtract(X3.x, G, X3.x);
|
|
|
+ LY3 := TSecP384R1FieldElement.Create(LS);
|
|
|
+ TSecP384R1Field.Subtract(LS, LX3.X, LY3.X);
|
|
|
+ TSecP384R1Field.Multiply(LY3.X, LM, LY3.X, LTT0);
|
|
|
+ TSecP384R1Field.Subtract(LY3.X, LT1, LY3.X);
|
|
|
|
|
|
- Y3 := TSecP384R1FieldElement.Create(G);
|
|
|
- TSecP384R1Field.Subtract(V, X3.x, Y3.x);
|
|
|
- TNat384.Mul(Y3.x, r, tt2);
|
|
|
- TSecP384R1Field.AddExt(tt1, tt2, tt1);
|
|
|
- TSecP384R1Field.Reduce(tt1, Y3.x);
|
|
|
+ LZ3 := TSecP384R1FieldElement.Create(LM);
|
|
|
+ TSecP384R1Field.Twice(LY1.X, LZ3.X);
|
|
|
+ if not LZ1IsOne then
|
|
|
+ TSecP384R1Field.Multiply(LZ3.X, LZ1.X, LZ3.X, LTT0);
|
|
|
|
|
|
- Z3 := TSecP384R1FieldElement.Create(H);
|
|
|
- if (not(Z1IsOne)) then
|
|
|
- begin
|
|
|
- TSecP384R1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
|
|
- end;
|
|
|
- if (not(Z2IsOne)) then
|
|
|
- begin
|
|
|
- TSecP384R1Field.Multiply(Z3.x, Z2.x, Z3.x);
|
|
|
- end;
|
|
|
-
|
|
|
- zs := TCryptoLibGenericArray<IECFieldElement>.Create(Z3);
|
|
|
+ LZs := TCryptoLibGenericArray<IECFieldElement>.Create(LZ3 as IECFieldElement);
|
|
|
+ Result := TSecP384R1Point.Create(LCurve, LX3 as IECFieldElement, LY3 as IECFieldElement, LZs);
|
|
|
+end;
|
|
|
|
|
|
- result := TSecP384R1Point.Create(Lcurve, X3, Y3, zs, IsCompressed)
|
|
|
- as IECPoint;
|
|
|
+function TSecP384R1Point.TwicePlus(const AB: IECPoint): IECPoint;
|
|
|
+begin
|
|
|
+ if (Self as IECPoint) = AB then
|
|
|
+ Exit(ThreeTimes());
|
|
|
+ if IsInfinity then
|
|
|
+ Exit(AB);
|
|
|
+ if AB.IsInfinity then
|
|
|
+ Exit(Twice());
|
|
|
+ if RawYCoord.IsZero then
|
|
|
+ Exit(AB);
|
|
|
+ Result := Twice().Add(AB);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Point.Detach: IECPoint;
|
|
|
+function TSecP384R1Point.ThreeTimes: IECPoint;
|
|
|
begin
|
|
|
- result := TSecP384R1Point.Create(Nil, AffineXCoord, AffineYCoord) as IECPoint;
|
|
|
+ if IsInfinity or RawYCoord.IsZero then
|
|
|
+ Exit(Self as IECPoint);
|
|
|
+ Result := Twice().Add(Self as IECPoint);
|
|
|
end;
|
|
|
|
|
|
function TSecP384R1Point.Negate: IECPoint;
|
|
|
begin
|
|
|
- if (IsInfinity) then
|
|
|
- begin
|
|
|
- result := Self as IECPoint;
|
|
|
- Exit;
|
|
|
- end;
|
|
|
+ if IsInfinity then
|
|
|
+ Exit(Self as IECPoint);
|
|
|
+ Result := TSecP384R1Point.Create(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords);
|
|
|
+end;
|
|
|
+
|
|
|
+{ TSecP384R1Curve.TSecP384R1LookupTable }
|
|
|
|
|
|
- result := TSecP384R1Point.Create(curve, RawXCoord, RawYCoord.Negate(),
|
|
|
- RawZCoords, IsCompressed) as IECPoint;
|
|
|
+constructor TSecP384R1Curve.TSecP384R1LookupTable.Create(const AOuter: ISecP384R1Curve;
|
|
|
+ const ATable: TCryptoLibUInt32Array; ASize: Int32);
|
|
|
+begin
|
|
|
+ Inherited Create;
|
|
|
+ FOuter := AOuter;
|
|
|
+ FTable := ATable;
|
|
|
+ FSize := ASize;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Point.ThreeTimes: IECPoint;
|
|
|
+function TSecP384R1Curve.TSecP384R1LookupTable.GetSize: Int32;
|
|
|
begin
|
|
|
- if ((IsInfinity) or (RawYCoord.IsZero)) then
|
|
|
- begin
|
|
|
- result := Self as IECPoint;
|
|
|
- Exit;
|
|
|
- end;
|
|
|
+ Result := FSize;
|
|
|
+end;
|
|
|
|
|
|
- // NOTE: Be careful about recursions between TwicePlus and ThreeTimes
|
|
|
- result := Twice().Add(Self as IECPoint);
|
|
|
+function TSecP384R1Curve.TSecP384R1LookupTable.CreatePoint(const AX, AY: TCryptoLibUInt32Array): IECPoint;
|
|
|
+begin
|
|
|
+ Result := FOuter.CreateRawPoint(TSecP384R1FieldElement.Create(AX) as IECFieldElement,
|
|
|
+ TSecP384R1FieldElement.Create(AY) as IECFieldElement, TSecP384R1Curve.SecP384R1AffineZs);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Point.Twice: IECPoint;
|
|
|
+function TSecP384R1Curve.TSecP384R1LookupTable.Lookup(AIndex: Int32): IECPoint;
|
|
|
var
|
|
|
- Lcurve: IECCurve;
|
|
|
- Y1, x1, Z1, X3, Y3, Z3: ISecP384R1FieldElement;
|
|
|
- c: UInt32;
|
|
|
- Y1Squared, Z1Squared, T, M, S, t1, t2: TCryptoLibUInt32Array;
|
|
|
- Z1IsOne: Boolean;
|
|
|
+ LX, LY: TCryptoLibUInt32Array;
|
|
|
+ LPos, LI, LJ: Int32;
|
|
|
+ LMask: UInt32;
|
|
|
begin
|
|
|
+ LX := TNat.Create(SECP384R1_FE_INTS);
|
|
|
+ LY := TNat.Create(SECP384R1_FE_INTS);
|
|
|
+ LPos := 0;
|
|
|
|
|
|
- if (IsInfinity) then
|
|
|
- begin
|
|
|
- result := Self as IECPoint;
|
|
|
- Exit;
|
|
|
- end;
|
|
|
-
|
|
|
- Lcurve := curve;
|
|
|
-
|
|
|
- Y1 := RawYCoord as ISecP384R1FieldElement;
|
|
|
- if (Y1.IsZero) then
|
|
|
- begin
|
|
|
- result := Lcurve.Infinity;
|
|
|
- Exit;
|
|
|
- end;
|
|
|
-
|
|
|
- x1 := RawXCoord as ISecP384R1FieldElement;
|
|
|
- Z1 := RawZCoords[0] as ISecP384R1FieldElement;
|
|
|
-
|
|
|
- t1 := TNat.Create(12);
|
|
|
- t2 := TNat.Create(12);
|
|
|
- Y1Squared := TNat.Create(12);
|
|
|
- TSecP384R1Field.Square(Y1.x, Y1Squared);
|
|
|
-
|
|
|
- T := TNat.Create(12);
|
|
|
- TSecP384R1Field.Square(Y1Squared, T);
|
|
|
-
|
|
|
- Z1IsOne := Z1.IsOne;
|
|
|
-
|
|
|
- Z1Squared := Z1.x;
|
|
|
- if (not(Z1IsOne)) then
|
|
|
+ for LI := 0 to System.Pred(FSize) do
|
|
|
begin
|
|
|
- Z1Squared := t2;
|
|
|
- TSecP384R1Field.Square(Z1.x, Z1Squared);
|
|
|
- end;
|
|
|
+ LMask := UInt32(TBitOperations.Asr32(((LI xor AIndex) - 1), 31));
|
|
|
|
|
|
- TSecP384R1Field.Subtract(x1.x, Z1Squared, t1);
|
|
|
-
|
|
|
- M := t2;
|
|
|
- TSecP384R1Field.Add(x1.x, Z1Squared, M);
|
|
|
- TSecP384R1Field.Multiply(M, t1, M);
|
|
|
- c := TNat.AddBothTo(12, M, M, M);
|
|
|
- TSecP384R1Field.Reduce32(c, M);
|
|
|
-
|
|
|
- S := Y1Squared;
|
|
|
- TSecP384R1Field.Multiply(Y1Squared, x1.x, S);
|
|
|
- c := TNat.ShiftUpBits(12, S, 2, 0);
|
|
|
- TSecP384R1Field.Reduce32(c, S);
|
|
|
-
|
|
|
- c := TNat.ShiftUpBits(12, T, 3, 0, t1);
|
|
|
- TSecP384R1Field.Reduce32(c, t1);
|
|
|
-
|
|
|
- X3 := TSecP384R1FieldElement.Create(T);
|
|
|
- TSecP384R1Field.Square(M, X3.x);
|
|
|
- TSecP384R1Field.Subtract(X3.x, S, X3.x);
|
|
|
- TSecP384R1Field.Subtract(X3.x, S, X3.x);
|
|
|
-
|
|
|
- Y3 := TSecP384R1FieldElement.Create(S);
|
|
|
- TSecP384R1Field.Subtract(S, X3.x, Y3.x);
|
|
|
- TSecP384R1Field.Multiply(Y3.x, M, Y3.x);
|
|
|
- TSecP384R1Field.Subtract(Y3.x, t1, Y3.x);
|
|
|
+ for LJ := 0 to System.Pred(SECP384R1_FE_INTS) do
|
|
|
+ begin
|
|
|
+ LX[LJ] := LX[LJ] xor (FTable[LPos + LJ] and LMask);
|
|
|
+ LY[LJ] := LY[LJ] xor (FTable[LPos + SECP384R1_FE_INTS + LJ] and LMask);
|
|
|
+ end;
|
|
|
|
|
|
- Z3 := TSecP384R1FieldElement.Create(M);
|
|
|
- TSecP384R1Field.Twice(Y1.x, Z3.x);
|
|
|
- if (not(Z1IsOne)) then
|
|
|
- begin
|
|
|
- TSecP384R1Field.Multiply(Z3.x, Z1.x, Z3.x);
|
|
|
+ LPos := LPos + (SECP384R1_FE_INTS * 2);
|
|
|
end;
|
|
|
|
|
|
- result := TSecP384R1Point.Create(Lcurve, X3, Y3,
|
|
|
- TCryptoLibGenericArray<IECFieldElement>.Create(Z3), IsCompressed)
|
|
|
- as IECPoint;
|
|
|
+ Result := CreatePoint(LX, LY);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Point.TwicePlus(const b: IECPoint): IECPoint;
|
|
|
+function TSecP384R1Curve.TSecP384R1LookupTable.LookupVar(AIndex: Int32): IECPoint;
|
|
|
var
|
|
|
- Y1: IECFieldElement;
|
|
|
+ LX, LY: TCryptoLibUInt32Array;
|
|
|
+ LPos, LJ: Int32;
|
|
|
begin
|
|
|
- if ((Self as IECPoint) = b) then
|
|
|
- begin
|
|
|
- result := ThreeTimes();
|
|
|
- Exit;
|
|
|
- end;
|
|
|
- if (IsInfinity) then
|
|
|
- begin
|
|
|
- result := b;
|
|
|
- Exit;
|
|
|
- end;
|
|
|
- if (b.IsInfinity) then
|
|
|
- begin
|
|
|
- result := Twice();
|
|
|
- Exit;
|
|
|
- end;
|
|
|
+ LX := TNat.Create(SECP384R1_FE_INTS);
|
|
|
+ LY := TNat.Create(SECP384R1_FE_INTS);
|
|
|
+ LPos := AIndex * SECP384R1_FE_INTS * 2;
|
|
|
|
|
|
- Y1 := RawYCoord;
|
|
|
- if (Y1.IsZero) then
|
|
|
+ for LJ := 0 to System.Pred(SECP384R1_FE_INTS) do
|
|
|
begin
|
|
|
- result := b;
|
|
|
- Exit;
|
|
|
+ LX[LJ] := FTable[LPos + LJ];
|
|
|
+ LY[LJ] := FTable[LPos + SECP384R1_FE_INTS + LJ];
|
|
|
end;
|
|
|
|
|
|
- result := Twice().Add(b);
|
|
|
+ Result := CreatePoint(LX, LY);
|
|
|
end;
|
|
|
|
|
|
{ TSecP384R1Curve }
|
|
|
|
|
|
-constructor TSecP384R1Curve.Create;
|
|
|
+class procedure TSecP384R1Curve.Boot;
|
|
|
begin
|
|
|
- Fq := TSecP384R1FieldElement.Q;
|
|
|
- Inherited Create(Fq);
|
|
|
- Fm_infinity := TSecP384R1Point.Create(Self as IECCurve, Nil, Nil);
|
|
|
- Fm_a := FromBigInteger(TBigInteger.Create(1,
|
|
|
- THex.Decode
|
|
|
- ('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC'))
|
|
|
- );
|
|
|
- Fm_b := FromBigInteger(TBigInteger.Create(1,
|
|
|
- THex.Decode
|
|
|
- ('B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF'))
|
|
|
- );
|
|
|
- Fm_order := TBigInteger.Create(1,
|
|
|
- THex.Decode
|
|
|
- ('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973')
|
|
|
- );
|
|
|
- Fm_cofactor := TBigInteger.One;
|
|
|
- Fm_coord := SECP384R1_DEFAULT_COORDS;
|
|
|
+ FQ := TSecP384R1FieldElement.Q;
|
|
|
+ FSecP384R1AffineZs := TCryptoLibGenericArray<IECFieldElement>.Create(
|
|
|
+ TSecP384R1FieldElement.Create(TBigInteger.One) as IECFieldElement);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.CloneCurve: IECCurve;
|
|
|
+class constructor TSecP384R1Curve.Create;
|
|
|
begin
|
|
|
- result := TSecP384R1Curve.Create();
|
|
|
+ Boot;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.CreateCacheSafeLookupTable(const points
|
|
|
- : TCryptoLibGenericArray<IECPoint>; off, len: Int32): IECLookupTable;
|
|
|
-var
|
|
|
- table: TCryptoLibUInt32Array;
|
|
|
- pos, i: Int32;
|
|
|
- P: IECPoint;
|
|
|
+constructor TSecP384R1Curve.Create;
|
|
|
begin
|
|
|
- System.SetLength(table, len * SECP384R1_FE_INTS * 2);
|
|
|
-
|
|
|
- pos := 0;
|
|
|
- for i := 0 to System.Pred(len) do
|
|
|
- begin
|
|
|
- P := points[off + i];
|
|
|
- TNat.Copy(SECP384R1_FE_INTS, (P.RawXCoord as ISecP384R1FieldElement).x, 0,
|
|
|
- table, pos);
|
|
|
- pos := pos + SECP384R1_FE_INTS;
|
|
|
- TNat.Copy(SECP384R1_FE_INTS, (P.RawYCoord as ISecP384R1FieldElement).x, 0,
|
|
|
- table, pos);
|
|
|
- pos := pos + SECP384R1_FE_INTS;
|
|
|
- end;
|
|
|
-
|
|
|
- result := TSecP384R1LookupTable.Create(Self as ISecP384R1Curve, table, len);
|
|
|
+ Inherited Create(TSecP384R1Curve.Q, True);
|
|
|
+ FInfinity := TSecP384R1Point.Create(Self as IECCurve, nil, nil);
|
|
|
+ FA := FromBigInteger(TBigInteger.Create(1, THex.Decode('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC')));
|
|
|
+ FB := FromBigInteger(TBigInteger.Create(1, THex.Decode('B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF')));
|
|
|
+ FOrder := TBigInteger.Create(1, THex.Decode('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973'));
|
|
|
+ FCofactor := TBigInteger.One;
|
|
|
+ FCoord := SECP384R1_DEFAULT_COORDS;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.CreateRawPoint(const x, y: IECFieldElement;
|
|
|
- withCompression: Boolean): IECPoint;
|
|
|
+destructor TSecP384R1Curve.Destroy;
|
|
|
begin
|
|
|
- result := TSecP384R1Point.Create(Self as IECCurve, x, y, withCompression);
|
|
|
+ FInfinity := nil;
|
|
|
+ inherited Destroy;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.CreateRawPoint(const x, y: IECFieldElement;
|
|
|
- const zs: TCryptoLibGenericArray<IECFieldElement>; withCompression: Boolean)
|
|
|
- : IECPoint;
|
|
|
+function TSecP384R1Curve.GetQ: TBigInteger;
|
|
|
begin
|
|
|
- result := TSecP384R1Point.Create(Self as IECCurve, x, y, zs, withCompression);
|
|
|
+ Result := TSecP384R1Curve.Q;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.FromBigInteger(const x: TBigInteger): IECFieldElement;
|
|
|
+function TSecP384R1Curve.CloneCurve: IECCurve;
|
|
|
begin
|
|
|
- result := TSecP384R1FieldElement.Create(x);
|
|
|
+ Result := TSecP384R1Curve.Create;
|
|
|
end;
|
|
|
|
|
|
function TSecP384R1Curve.GetFieldSize: Int32;
|
|
|
begin
|
|
|
- result := Fq.BitLength;
|
|
|
+ Result := TSecP384R1Curve.Q.BitLength;
|
|
|
end;
|
|
|
|
|
|
function TSecP384R1Curve.GetInfinity: IECPoint;
|
|
|
begin
|
|
|
- result := Fm_infinity;
|
|
|
+ Result := FInfinity;
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.GetQ: TBigInteger;
|
|
|
+function TSecP384R1Curve.FromBigInteger(const AX: TBigInteger): IECFieldElement;
|
|
|
begin
|
|
|
- result := Fq;
|
|
|
+ Result := TSecP384R1FieldElement.Create(AX);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.SupportsCoordinateSystem(coord: Int32): Boolean;
|
|
|
+function TSecP384R1Curve.CreateRawPoint(const AX, AY: IECFieldElement): IECPoint;
|
|
|
begin
|
|
|
- case coord of
|
|
|
- TECCurveConstants.COORD_JACOBIAN:
|
|
|
- result := true
|
|
|
- else
|
|
|
- result := false;
|
|
|
- end;
|
|
|
+ Result := TSecP384R1Point.Create(Self as IECCurve, AX, AY);
|
|
|
end;
|
|
|
|
|
|
-{ TSecP384R1Curve.TSecP384R1LookupTable }
|
|
|
-
|
|
|
-constructor TSecP384R1Curve.TSecP384R1LookupTable.Create
|
|
|
- (const outer: ISecP384R1Curve; const table: TCryptoLibUInt32Array;
|
|
|
- size: Int32);
|
|
|
+function TSecP384R1Curve.CreateRawPoint(const AX, AY: IECFieldElement;
|
|
|
+ const AZs: TCryptoLibGenericArray<IECFieldElement>): IECPoint;
|
|
|
begin
|
|
|
- Inherited Create();
|
|
|
- Fm_outer := outer;
|
|
|
- Fm_table := table;
|
|
|
- Fm_size := size;
|
|
|
+ Result := TSecP384R1Point.Create(Self as IECCurve, AX, AY, AZs);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.TSecP384R1LookupTable.CreatePoint(const x,
|
|
|
- y: TCryptoLibUInt32Array): IECPoint;
|
|
|
+function TSecP384R1Curve.CreateCacheSafeLookupTable(const APoints: TCryptoLibGenericArray<IECPoint>;
|
|
|
+ AOff, ALen: Int32): IECLookupTable;
|
|
|
var
|
|
|
- XFieldElement, YFieldElement: ISecP384R1FieldElement;
|
|
|
- SECP384R1_AFFINE_ZS: TCryptoLibGenericArray<IECFieldElement>;
|
|
|
+ LTable: TCryptoLibUInt32Array;
|
|
|
+ LPos, LI: Int32;
|
|
|
+ LP: IECPoint;
|
|
|
begin
|
|
|
- SECP384R1_AFFINE_ZS := TCryptoLibGenericArray<IECFieldElement>.Create
|
|
|
- (TSecP384R1FieldElement.Create(TBigInteger.One) as ISecP384R1FieldElement);
|
|
|
-
|
|
|
- XFieldElement := TSecP384R1FieldElement.Create(x);
|
|
|
- YFieldElement := TSecP384R1FieldElement.Create(y);
|
|
|
- result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement,
|
|
|
- SECP384R1_AFFINE_ZS, false);
|
|
|
+ System.SetLength(LTable, ALen * SECP384R1_FE_INTS * 2);
|
|
|
+ LPos := 0;
|
|
|
+ for LI := 0 to System.Pred(ALen) do
|
|
|
+ begin
|
|
|
+ LP := APoints[AOff + LI];
|
|
|
+ TNat.Copy(SECP384R1_FE_INTS, (LP.RawXCoord as ISecP384R1FieldElement).X, 0, LTable, LPos);
|
|
|
+ LPos := LPos + SECP384R1_FE_INTS;
|
|
|
+ TNat.Copy(SECP384R1_FE_INTS, (LP.RawYCoord as ISecP384R1FieldElement).X, 0, LTable, LPos);
|
|
|
+ LPos := LPos + SECP384R1_FE_INTS;
|
|
|
+ end;
|
|
|
+ Result := TSecP384R1LookupTable.Create(Self as ISecP384R1Curve, LTable, ALen);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.TSecP384R1LookupTable.GetSize: Int32;
|
|
|
+function TSecP384R1Curve.RandomFieldElement(const ARandom: ISecureRandom): IECFieldElement;
|
|
|
+var
|
|
|
+ LX: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- result := Fm_size;
|
|
|
+ LX := TNat.Create(12);
|
|
|
+ TSecP384R1Field.Random(ARandom, LX);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LX);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.TSecP384R1LookupTable.Lookup(index: Int32): IECPoint;
|
|
|
+function TSecP384R1Curve.RandomFieldElementMult(const ARandom: ISecureRandom): IECFieldElement;
|
|
|
var
|
|
|
- x, y: TCryptoLibUInt32Array;
|
|
|
- pos, i, J: Int32;
|
|
|
- MASK: UInt32;
|
|
|
+ LX: TCryptoLibUInt32Array;
|
|
|
begin
|
|
|
- x := TNat.Create(SECP384R1_FE_INTS);
|
|
|
- y := TNat.Create(SECP384R1_FE_INTS);
|
|
|
- pos := 0;
|
|
|
-
|
|
|
- for i := 0 to System.Pred(Fm_size) do
|
|
|
- begin
|
|
|
- MASK := UInt32(TBitOperations.Asr32((i xor index) - 1, 31));
|
|
|
-
|
|
|
- for J := 0 to System.Pred(SECP384R1_FE_INTS) do
|
|
|
- begin
|
|
|
- x[J] := x[J] xor (Fm_table[pos + J] and MASK);
|
|
|
- y[J] := y[J] xor (Fm_table[pos + SECP384R1_FE_INTS + J] and MASK);
|
|
|
- end;
|
|
|
-
|
|
|
- pos := pos + (SECP384R1_FE_INTS * 2);
|
|
|
- end;
|
|
|
-
|
|
|
- result := CreatePoint(x, y)
|
|
|
+ LX := TNat.Create(12);
|
|
|
+ TSecP384R1Field.RandomMult(ARandom, LX);
|
|
|
+ Result := TSecP384R1FieldElement.Create(LX);
|
|
|
end;
|
|
|
|
|
|
-function TSecP384R1Curve.TSecP384R1LookupTable.LookupVar(index: Int32)
|
|
|
- : IECPoint;
|
|
|
-var
|
|
|
- x, y: TCryptoLibUInt32Array;
|
|
|
- pos, J: Int32;
|
|
|
+function TSecP384R1Curve.SupportsCoordinateSystem(ACoord: Int32): Boolean;
|
|
|
begin
|
|
|
- x := TNat.Create(SECP384R1_FE_INTS);
|
|
|
- y := TNat.Create(SECP384R1_FE_INTS);
|
|
|
- pos := index * SECP384R1_FE_INTS * 2;
|
|
|
-
|
|
|
- for J := 0 to System.Pred(SECP384R1_FE_INTS) do
|
|
|
- begin
|
|
|
- x[J] := Fm_table[pos + J];
|
|
|
- y[J] := Fm_table[pos + SECP384R1_FE_INTS + J];
|
|
|
+ case ACoord of
|
|
|
+ TECCurveConstants.COORD_JACOBIAN:
|
|
|
+ Result := True;
|
|
|
+ else
|
|
|
+ Result := False;
|
|
|
end;
|
|
|
-
|
|
|
- result := CreatePoint(x, y)
|
|
|
end;
|
|
|
|
|
|
end.
|