import { KeyAgreement } from "./keyagreement" ; import { concat } from "@stablelib/bytes" ; /**
 * ConcatKeyAgreement concatenates many key agreements into one.
 * Each message is a concatenation of underlying key agreement
 * messages, and shared key is a concatenation of all shared keys.
 */ export class ConcatKeyAgreement implements KeyAgreement { readonly offerMessageLength = 0 ; readonly acceptMessageLength = 0 ; readonly sharedKeyLength = 0 ; readonly savedStateLength = 0 ; constructor ( public agreements ) { for ( let i = 0 ; i < agreements . length ; i ++ ) { const a = agreements [ i ] ; this . offerMessageLength += a . offerMessageLength ; this . acceptMessageLength += a . acceptMessageLength ; this . sharedKeyLength += a . sharedKeyLength ; this . savedStateLength += a . savedStateLength ; } } saveState ( ) { return concat . apply ( null , this . agreements . map ( a => a . saveState ( ) ) ) ; } restoreState ( savedState ) { let offset = 0 ; this . agreements . forEach ( a => { a . restoreState ( savedState . subarray ( offset , offset + a . savedStateLength ) ) ; offset += a . savedStateLength ; } ) ; return this ; } clean ( ) { this . agreements . forEach ( a => a . clean ( ) ) ; } offer ( ) { return concat . apply ( null , this . agreements . map ( a => a . offer ( ) ) ) ; } accept ( offerMsg ) { if ( offerMsg . length !== this . offerMessageLength ) { throw new Error ( "KeyAgreement: incorrect offer message length" ) ; } let offset = 0 ; let results = [ ] ; this . agreements . forEach ( a => { results . push ( a . accept ( offerMsg . subarray ( offset , offset + a . offerMessageLength ) ) ) ; offset += a . offerMessageLength ; } ) ; return concat . apply ( null , results ) ; } finish ( acceptMsg ) { if ( acceptMsg . length !== this . acceptMessageLength ) { throw new Error ( "KeyAgreement: incorrect accept message length" ) ; } let offset = 0 ; this . agreements . forEach ( a => { a . finish ( acceptMsg . subarray ( offset , offset + a . acceptMessageLength ) ) ; offset += a . acceptMessageLength ; } ) ; return this ; } getSharedKey ( ) { return concat . apply ( null , this . agreements . map ( a => a . getSharedKey ( ) ) ) ; } }