77
88import { randomBytes , RandomSource } from "@stablelib/random" ;
99import { wipe } from "@stablelib/wipe" ;
10- import { KeyAgreement } from "@stablelib/keyagreement" ;
1110
1211export const PUBLIC_KEY_LENGTH = 32 ;
1312export const SECRET_KEY_LENGTH = 32 ;
1413export const SHARED_KEY_LENGTH = 32 ;
1514
16- // TODO(dchest): some functions ara copies of ../sign/ed25519.
15+ // TODO(dchest): some functions are copies of ../sign/ed25519.
1716// Find a way to combine them without opening up to public.
1817
1918// Ported from TweetNaCl.js, which is ported from TweetNaCl
@@ -602,16 +601,16 @@ export function generateKeyPair(prng?: RandomSource): KeyPair {
602601 * From RFC 7748:
603602 *
604603 * > Protocol designers using Diffie-Hellman over the curves defined in
605- * > this document must not assume "contributory behaviour ". Specially,
606- * > contributory behaviour means that both parties' private keys
604+ * > this document must not assume "contributory behavior ". Specially,
605+ * > contributory behavior means that both parties' private keys
607606 * > contribute to the resulting shared key. Since curve25519 and
608607 * > curve448 have cofactors of 8 and 4 (respectively), an input point of
609608 * > small order will eliminate any contribution from the other party's
610609 * > private key. This situation can be detected by checking for the all-
611610 * > zero output, which implementations MAY do, as specified in Section 6.
612611 * > However, a large number of existing implementations do not do this.
613612 *
614- * Important : the returned key is a raw result of scalar multiplication.
613+ * IMPORTANT : the returned key is a raw result of scalar multiplication.
615614 * To use it as a key material, hash it with a cryptographic hash function.
616615 */
617616export function sharedKey ( mySecretKey : Uint8Array , theirPublicKey : Uint8Array , rejectZero = false ) : Uint8Array {
@@ -636,90 +635,3 @@ export function sharedKey(mySecretKey: Uint8Array, theirPublicKey: Uint8Array, r
636635
637636 return result ;
638637}
639-
640-
641- /** Constants for key agreement */
642- export const OFFER_MESSAGE_LENGTH = PUBLIC_KEY_LENGTH ;
643- export const ACCEPT_MESSAGE_LENGTH = PUBLIC_KEY_LENGTH ;
644- export const SAVED_STATE_LENGTH = SECRET_KEY_LENGTH ;
645- export const SECRET_SEED_LENGTH = SECRET_KEY_LENGTH ;
646-
647- /**
648- * X25519 key agreement using ephemeral key pairs.
649- *
650- * Note that unless this key agreement is combined withan authentication
651- * method, such as public key signatures, it's vulnerable to man-in-the-middle
652- * attacks.
653- */
654- export class X25519KeyAgreement implements KeyAgreement {
655- readonly offerMessageLength = OFFER_MESSAGE_LENGTH ;
656- readonly acceptMessageLength = ACCEPT_MESSAGE_LENGTH ;
657- readonly sharedKeyLength = SHARED_KEY_LENGTH ;
658- readonly savedStateLength = SAVED_STATE_LENGTH ;
659-
660- private _secretKey : Uint8Array ;
661- private _sharedKey : Uint8Array | undefined ;
662- private _offered = false ;
663-
664- constructor ( secretSeed ?: Uint8Array , prng ?: RandomSource ) {
665- this . _secretKey = secretSeed || randomBytes ( SECRET_KEY_LENGTH , prng ) ;
666- }
667-
668- saveState ( ) : Uint8Array {
669- return new Uint8Array ( this . _secretKey ) ;
670- }
671-
672- restoreState ( savedState : Uint8Array ) : this {
673- this . _secretKey = new Uint8Array ( savedState ) ;
674- return this ;
675- }
676-
677- clean ( ) : void {
678- if ( this . _secretKey ) {
679- wipe ( this . _secretKey ) ;
680- }
681- if ( this . _sharedKey ) {
682- wipe ( this . _sharedKey ) ;
683- }
684- }
685-
686- offer ( ) : Uint8Array {
687- this . _offered = true ;
688- const keyPair = generateKeyPairFromSeed ( this . _secretKey ) ;
689- return keyPair . publicKey ;
690- }
691-
692- accept ( offerMsg : Uint8Array ) : Uint8Array {
693- if ( this . _offered ) {
694- throw new Error ( "X25519KeyAgreement: accept shouldn't be called by offering party" ) ;
695- }
696- if ( offerMsg . length !== this . offerMessageLength ) {
697- throw new Error ( "X25519KeyAgreement: incorrect offer message length" ) ;
698- }
699- const keyPair = generateKeyPairFromSeed ( this . _secretKey ) ;
700- this . _sharedKey = sharedKey ( keyPair . secretKey , offerMsg ) ;
701- wipe ( keyPair . secretKey ) ;
702- return keyPair . publicKey ;
703- }
704-
705- finish ( acceptMsg : Uint8Array ) : this {
706- if ( acceptMsg . length !== this . acceptMessageLength ) {
707- throw new Error ( "X25519KeyAgreement: incorrect accept message length" ) ;
708- }
709- if ( ! this . _secretKey ) {
710- throw new Error ( "X25519KeyAgreement: no offer state" ) ;
711- }
712- if ( this . _sharedKey ) {
713- throw new Error ( "X25519KeyAgreement: finish was already called" ) ;
714- }
715- this . _sharedKey = sharedKey ( this . _secretKey , acceptMsg ) ;
716- return this ;
717- }
718-
719- getSharedKey ( ) : Uint8Array {
720- if ( ! this . _sharedKey ) {
721- throw new Error ( "X25519KeyAgreement: no shared key established" ) ;
722- }
723- return new Uint8Array ( this . _sharedKey ) ;
724- }
725- }
0 commit comments