Private/Get-LagrangeInterpolation.ps1
<# .SYNOPSIS Performs Lagrange interpolation over a finite field. .DESCRIPTION Performs Lagrange interpolation over a finite field to recover a secret value. .PARAMETER x The input value to interpolate. .PARAMETER PointNums An array of point numbers. .PARAMETER PointPolynomials An array of polynomial values at the corresponding point numbers. .PARAMETER Prime The prime modulus of the finite field. .OUTPUTS The interpolated secret value. .EXAMPLE Interpolate a secret value: $x = 5 $PointNums = @(1, 2, 3) $PointPolynomials = @(2, 4, 9) $Prime = 11 Get-LagrangeInterpolation -x $x -PointNums $PointNums -PointPolynomials $PointPolynomials -Prime $Prime #> Function Get-LagrangeInterpolation { Param( $x, [bigint[]]$PointNums, [bigint[]]$PointPolynomials, [bigint]$Prime ) If($PointNums.Count -ne ($PointNums | Select-Object -Unique).Count) { throw 'Share ids need to be unique' } $PointCount = $PointNums.Count $Numerators = [System.Collections.ArrayList]@() $Denominators = [System.Collections.ArrayList]@() 0..($PointCount-1) | Foreach-Object { $Others = [System.Collections.ArrayList]$PointNums $Current = $Others[$_] $Others.RemoveAt($_) $Numerators.Add((Get-InputProduct -Values ($Others | Foreach-Object { $x - $_ }))) | Out-Null $Denominators.Add((Get-InputProduct -Values ($Others | Foreach-Object { $Current - $_ }))) | Out-Null } $Denominator = Get-InputProduct -Values $Denominators $NumeratorTotal = Foreach($i in 0..($PointCount-1)) { # Make sure the numerator is positive $Num = Get-PythonModulus -Operant ($Numerators[$i] * $Denominator * $PointPolynomials[$i]) -Modulus $Prime If($Numerators[$i] -eq 42) { $print = $true} Else {$print = $false} Get-DivMod -Numerator $Num -Denominator $Denominators[$i] -Prime $Prime -print $print } [bigint]$NumeratorSum = 0 $NumeratorTotal | ForEach-Object { $NumeratorSum += $_ } $Secret = Get-PythonModulus -Operant (Get-DivMod -Numerator $NumeratorSum -Denominator $Denominator -Prime $Prime) -Modulus $Prime Return $Secret } |