Tests/Private/Shamir.Tests.ps1
|
BeforeDiscovery { Import-Module (Join-Path $PSScriptRoot '../../Posh-SecretSharing.psd1') -Force } Describe 'Private/Shamir' -Tag Unit { InModuleScope 'Posh-SecretSharing' { Describe 'Get-SecretSharingRandomByte' { It 'returns the requested number of bytes' { (Get-SecretSharingRandomByte -Length 16).Count | Should -Be 16 } It 'does not return the same bytes on two successive calls' { $a = Get-SecretSharingRandomByte -Length 32 $b = Get-SecretSharingRandomByte -Length 32 (Compare-Object $a $b) | Should -Not -BeNullOrEmpty } } Describe 'Invoke-SecretSharingShamirInterpolation' { It 'returns the matching point directly when X is already known' { $points = @( [PSCustomObject]@{ X = [byte]1; Value = [byte[]](10, 20, 30) } [PSCustomObject]@{ X = [byte]2; Value = [byte[]](40, 50, 60) } ) $actual = Invoke-SecretSharingShamirInterpolation -Point $points -X 1 $actual | Should -Be ([byte[]](10, 20, 30)) } It 'reconstructs the constant term of a known degree-1 polynomial from any 2 of its points' { $secret = [byte[]](0xAB, 0x11) $coefficient = [byte[]](0x07, 0x9A) $points = 1..3 | ForEach-Object { $x = [byte]$_ $value = for ($i = 0; $i -lt $secret.Length; $i++) { $term = Invoke-SecretSharingFieldMultiplication -A $coefficient[$i] -B $x Invoke-SecretSharingFieldAddition -A $secret[$i] -B $term } [PSCustomObject]@{ X = $x; Value = [byte[]]$value } } $actual1 = Invoke-SecretSharingShamirInterpolation -Point $points[0, 1] -X 0 $actual1 | Should -Be $secret $actual2 = Invoke-SecretSharingShamirInterpolation -Point $points[1, 2] -X 0 $actual2 | Should -Be $secret } It 'throws on duplicate X-coordinates' { $points = @( [PSCustomObject]@{ X = [byte]5; Value = [byte[]](1, 2) } [PSCustomObject]@{ X = [byte]5; Value = [byte[]](3, 4) } ) { Invoke-SecretSharingShamirInterpolation -Point $points -X 0 } | Should -Throw } It 'throws when point values have inconsistent lengths' { $points = @( [PSCustomObject]@{ X = [byte]1; Value = [byte[]](1, 2) } [PSCustomObject]@{ X = [byte]2; Value = [byte[]](3, 4, 5) } ) { Invoke-SecretSharingShamirInterpolation -Point $points -X 0 } | Should -Throw } } Describe 'Split-SecretSharingShamirSecret' { It 'returns the secret itself for every share when Threshold is 1' { $secret = [byte[]](1, 2, 3, 4) $shares = Split-SecretSharingShamirSecret -Secret $secret -SecretXCoordinate 255 -Threshold 1 -XCoordinate ([byte[]](0, 1, 2)) foreach ($share in $shares) { $share.Value | Should -Be $secret } } It 'reconstructs the original secret from any Threshold of the returned shares' { $secret = Get-SecretSharingRandomByte -Length 8 $shares = Split-SecretSharingShamirSecret -Secret $secret -SecretXCoordinate 255 -Threshold 3 -XCoordinate ([byte[]](0, 1, 2, 3, 4)) $subset = $shares[1, 3, 4] | ForEach-Object { [PSCustomObject]@{ X = $_.X; Value = $_.Value } } $actual = Invoke-SecretSharingShamirInterpolation -Point $subset -X 255 $actual | Should -Be $secret } It 'produces different shares for the same secret on repeated calls' { $secret = [byte[]](9, 9, 9, 9) $sharesA = Split-SecretSharingShamirSecret -Secret $secret -SecretXCoordinate 255 -Threshold 3 -XCoordinate ([byte[]](0, 1, 2)) $sharesB = Split-SecretSharingShamirSecret -Secret $secret -SecretXCoordinate 255 -Threshold 3 -XCoordinate ([byte[]](0, 1, 2)) ($sharesA[0].Value -join ',') | Should -Not -Be ($sharesB[0].Value -join ',') } It 'incorporates a supplied FixedPoint anchor into the reconstructed polynomial' { $secret = [byte[]](5, 6, 7, 8) $fixedPoint = @([PSCustomObject]@{ X = [byte]254; Value = (Get-SecretSharingRandomByte -Length 4) }) $shares = Split-SecretSharingShamirSecret -Secret $secret -SecretXCoordinate 255 -Threshold 3 -XCoordinate ([byte[]](0, 1, 2, 3)) -FixedPoint $fixedPoint $subset = @($shares[0], $shares[1]) + $fixedPoint $actual = Invoke-SecretSharingShamirInterpolation -Point $subset -X 255 $actual | Should -Be $secret } It 'throws when there are not enough XCoordinate slots for the required random shares' { { Split-SecretSharingShamirSecret -Secret ([byte[]](1, 2)) -SecretXCoordinate 255 -Threshold 5 -XCoordinate ([byte[]](0, 1)) } | Should -Throw } It 'throws when a threshold of 1 is combined with a FixedPoint anchor' { $fixedPoint = @([PSCustomObject]@{ X = [byte]254; Value = [byte[]](1, 2) }) { Split-SecretSharingShamirSecret -Secret ([byte[]](1, 2)) -SecretXCoordinate 255 -Threshold 1 -XCoordinate ([byte[]](0)) -FixedPoint $fixedPoint } | Should -Throw } } } } |