Tests/Private/Share.Tests.ps1
|
BeforeDiscovery { Import-Module (Join-Path $PSScriptRoot '../../Posh-SecretSharing.psd1') -Force } Describe 'Private/Share' -Tag Unit { InModuleScope 'Posh-SecretSharing' { Describe 'ConvertTo-SecretSharingBigIntegerFromByte / ConvertFrom-SecretSharingBigIntegerToByte' { It 'round-trips an arbitrary byte array' { $bytes = [byte[]](0x01, 0x02, 0x03) $bi = ConvertTo-SecretSharingBigIntegerFromByte -Byte $bytes $bi | Should -Be 66051 $back = ConvertFrom-SecretSharingBigIntegerToByte -Value $bi -Length 3 $back | Should -Be $bytes } It 'treats the most-significant input byte as unsigned even when its high bit is set' { $bytes = [byte[]](0xFF, 0x00, 0x00, 0x00) $bi = ConvertTo-SecretSharingBigIntegerFromByte -Byte $bytes $bi | Should -BeGreaterThan 0 $bi | Should -Be 4278190080 $back = ConvertFrom-SecretSharingBigIntegerToByte -Value $bi -Length 4 $back | Should -Be $bytes } It 'round-trips a full 32-byte (256-bit) value' { $bytes = [byte[]](1..32 | ForEach-Object { 0xFF }) $bi = ConvertTo-SecretSharingBigIntegerFromByte -Byte $bytes $back = ConvertFrom-SecretSharingBigIntegerToByte -Value $bi -Length 32 $back | Should -Be $bytes } It 'zero-pads a value smaller than the requested length' { $back = ConvertFrom-SecretSharingBigIntegerToByte -Value ([System.Numerics.BigInteger]5) -Length 4 $back | Should -Be ([byte[]](0x00, 0x00, 0x00, 0x05)) } It 'throws when the value does not fit in the requested length' { $tooBig = [System.Numerics.BigInteger]::Parse('999999999999999999999999999999999999999999') { ConvertFrom-SecretSharingBigIntegerToByte -Value $tooBig -Length 4 } | Should -Throw } It 'treats an empty byte array as zero' { (ConvertTo-SecretSharingBigIntegerFromByte -Byte ([byte[]]@())) | Should -Be 0 } } Describe 'ConvertTo-SecretSharingWordIndex / ConvertFrom-SecretSharingWordIndex' { It 'splits a known integer into the expected base-1024 digits' { $digit = ConvertTo-SecretSharingWordIndex -Value 1234567 -Length 3 -RadixBit 10 $digit.Count | Should -Be 3 $expected = [System.Numerics.BigInteger]0 foreach ($d in $digit) { $expected = ($expected * 1024) + $d } $expected | Should -Be 1234567 } It 'round-trips through ConvertFrom' { $digit = ConvertTo-SecretSharingWordIndex -Value 987654 -Length 3 -RadixBit 10 (ConvertFrom-SecretSharingWordIndex -Index $digit -RadixBit 10) | Should -Be 987654 } It 'works with a 4-bit radix (share-parameter fields)' { $digit = ConvertTo-SecretSharingWordIndex -Value 0xABCDE -Length 5 -RadixBit 4 $digit | Should -Be @(0xA, 0xB, 0xC, 0xD, 0xE) } It 'left-pads with zero digits when Length exceeds what the value needs' { $digit = ConvertTo-SecretSharingWordIndex -Value 5 -Length 4 -RadixBit 10 $digit | Should -Be @(0, 0, 0, 5) } } Describe 'ConvertTo-SecretSharingShareWord / ConvertFrom-SecretSharingShareWord' { It 'round-trips a full set of header fields and a 16-byte value' { $value = 1..16 | ForEach-Object { [byte]$_ } $words = ConvertTo-SecretSharingShareWord -Identifier 12345 -IterationExponent 3 ` -GroupIndex 2 -GroupThreshold 3 -GroupCount 5 -MemberIndex 1 -MemberThreshold 2 -Value $value $decoded = ConvertFrom-SecretSharingShareWord -Index $words $decoded.Identifier | Should -Be 12345 $decoded.Extendable | Should -BeFalse $decoded.IterationExponent | Should -Be 3 $decoded.GroupIndex | Should -Be 2 $decoded.GroupThreshold | Should -Be 3 $decoded.GroupCount | Should -Be 5 $decoded.MemberIndex | Should -Be 1 $decoded.MemberThreshold | Should -Be 2 $decoded.Value | Should -Be $value } It 'round-trips the Extendable flag' { $value = 1..16 | ForEach-Object { [byte]$_ } $words = ConvertTo-SecretSharingShareWord -Identifier 1 -Extendable -IterationExponent 0 ` -GroupIndex 0 -GroupThreshold 1 -GroupCount 1 -MemberIndex 0 -MemberThreshold 1 -Value $value (ConvertFrom-SecretSharingShareWord -Index $words).Extendable | Should -BeTrue } It 'round-trips boundary field values (Identifier 0 and 32767, all 4-bit fields at their max)' { $value = 1..32 | ForEach-Object { [byte](256 - $_) } $words = ConvertTo-SecretSharingShareWord -Identifier 32767 -IterationExponent 15 ` -GroupIndex 15 -GroupThreshold 16 -GroupCount 16 -MemberIndex 15 -MemberThreshold 16 -Value $value $decoded = ConvertFrom-SecretSharingShareWord -Index $words $decoded.Identifier | Should -Be 32767 $decoded.IterationExponent | Should -Be 15 $decoded.GroupIndex | Should -Be 15 $decoded.GroupThreshold | Should -Be 16 $decoded.GroupCount | Should -Be 16 $decoded.MemberIndex | Should -Be 15 $decoded.MemberThreshold | Should -Be 16 $decoded.Value | Should -Be $value $words0 = ConvertTo-SecretSharingShareWord -Identifier 0 -IterationExponent 0 ` -GroupIndex 0 -GroupThreshold 1 -GroupCount 1 -MemberIndex 0 -MemberThreshold 1 -Value $value (ConvertFrom-SecretSharingShareWord -Index $words0).Identifier | Should -Be 0 } It 'round-trips a 32-byte (256-bit) value' { $value = 1..32 | ForEach-Object { [byte]$_ } $words = ConvertTo-SecretSharingShareWord -Identifier 500 -IterationExponent 0 ` -GroupIndex 0 -GroupThreshold 1 -GroupCount 1 -MemberIndex 0 -MemberThreshold 1 -Value $value (ConvertFrom-SecretSharingShareWord -Index $words).Value | Should -Be $value } It 'throws when GroupCount is less than GroupThreshold' { # ConvertTo-SecretSharingShareWord does not cross-validate Threshold vs Count (only # ConvertFrom does, mirroring the reference implementation's own decode-side check), # so encoding GroupThreshold > GroupCount succeeds and lets us exercise that check. $value = 1..16 | ForEach-Object { [byte]$_ } $words = ConvertTo-SecretSharingShareWord -Identifier 1 -IterationExponent 0 ` -GroupIndex 0 -GroupThreshold 5 -GroupCount 3 -MemberIndex 0 -MemberThreshold 1 -Value $value { ConvertFrom-SecretSharingShareWord -Index $words } | Should -Throw } It 'throws when given fewer than the minimum number of words' { { ConvertFrom-SecretSharingShareWord -Index ([int[]](1, 2, 3)) } | Should -Throw } } } } |